package the8472.utils.concurrent;
import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.function.Consumer;
public class LoggingScheduledThreadPoolExecutor extends ScheduledThreadPoolExecutor {
public static class NamedDaemonThreadFactory implements ThreadFactory {
final String name;
public NamedDaemonThreadFactory(String name) {
this.name = name;
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
t.setDaemon(true);
t.setName(name);
return t;
}
}
public static ThreadFactory namedDaemonFactory(String name) {
return new NamedDaemonThreadFactory(name);
}
final Consumer<Throwable> exceptionHandler;
public LoggingScheduledThreadPoolExecutor(int corePoolSize, ThreadFactory threadFactory, Consumer<Throwable> exceptionHandler) {
super(corePoolSize, threadFactory);
Objects.requireNonNull(exceptionHandler);
this.exceptionHandler = exceptionHandler;
}
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if(r instanceof FutureTask<?>) {
FutureTask<?> ft = (FutureTask<?>) r;
if(ft.isDone() && !ft.isCancelled()) {
try {
ft.get();
} catch (InterruptedException | ExecutionException e) {
exceptionHandler.accept(e.getCause());
}
}
if(t != null)
exceptionHandler.accept(t);
}
}
}