我有一个ScheduledExecutorService
的实例-根据某些业务需求,线程池大小为1-一段时间后开始挂起。作业仍在提交,线程池仍在“运行”,但是任务从未执行。
为了防止线程永远运行,我添加了一个超时,该超时可以在给定的超时后异常地完成任务。一切在本地都可以正常工作(包括超时),但是当部署到服务器时,一段时间后它开始挂起。
我猜这是由任务执行过程中的一些锁定引起的,但是我希望超时可以解决此问题(我错过了什么吗?)。
负责运行任务的方法:
private synchronized <T> CompletableFuture<T> submit(Supplier<T> supplier, ScheduledExecutorService delegate) {
CompletableFuture<T> completableFuture = new CompletableFuture<>();
completableFuture.whenComplete((input, exception) -> {
if (completableFuture.isCompletedExceptionally()) {
log.error("Error executing", exception);
}
});
delegate.schedule(() -> {
Timeouter timeouter = new Timeouter(30, completableFuture);
completableFuture.complete(new Task<>(supplier).run(completableFuture, timeouter));
}, 10, TimeUnit.SECONDS);
return completableFuture;
}
以及负责超时的助手类:
public class Timeouter extends TimerTask {
private Timer timer = new Timer();
private int timeout;
private CompletableFuture<?> completableFuture;
Timeouter(int timeout, CompletableFuture<?> completableFuture) {
this.timeout = timeout;
this.completableFuture = completableFuture;
}
public void start() {
timer.schedule(this, Duration.ofSeconds(timeout).toMillis());
}
void stop() {
timer.cancel();
timer.purge();
}
@Override
public void run() {
completableFuture.completeExceptionally(
new TimeoutException(String.format("Job timed-out after %s seconds", timeout)));
}
}
public class Task<T> {
private Supplier<T> supplier;
public Task(Supplier<T> supplier) {
this.supplier = supplier;
}
public T run(CompletableFuture<T> completableFuture, Timeouter timeouter) {
timeouter.start();
try {
T response = supplier.get();
return response;
} catch (Throwable t) {
completableFuture.completeExceptionally(t);
return null;
} finally {
timeouter.stop();
}
}
}
任何帮助将不胜感激。