任务执行期间ScheduledExecutorService冻结

时间:2019-10-28 09:02:17

标签: java multithreading threadpool

我有一个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();
        }
    }
}

任何帮助将不胜感激。

0 个答案:

没有答案