首页 > Java > java教程 > 如何在 ExecutorService 中实现可中断任务的超时?

如何在 ExecutorService 中实现可中断任务的超时?

DDD
发布: 2024-12-11 14:54:11
原创
864 人浏览过

How Can I Implement a Timeout for Interruptable Tasks in an ExecutorService?

可中断任务超时的 ExecutorService

并发执行任务时,通常需要一种机制来优雅地中断超出指定时间的任务暂停。这在长时间运行的任务可能导致应用程序锁定或性能问题的情况下特别有用。

实现 TimeoutExecutorService

这是一个 TimeoutThreadPoolExecutor 的实现,它扩展了标准 ThreadPoolExecutor 并包含超时功能:

class TimeoutThreadPoolExecutor extends ThreadPoolExecutor {

    private final long timeout;
    private final TimeUnit timeoutUnit;

    private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
    private final ConcurrentMap<Runnable, ScheduledFuture> runningTasks = new ConcurrentHashMap<>();

    public TimeoutThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, long timeout, TimeUnit timeoutUnit) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        this.timeout = timeout;
        this.timeoutUnit = timeoutUnit;
    }

    // Override methods to implement timeout behavior

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        if (timeout > 0) {
            ScheduledFuture scheduled = timeoutExecutor.schedule(new TimeoutTask(t), timeout, timeoutUnit);
            runningTasks.put(r, scheduled);
        }
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        ScheduledFuture timeoutTask = runningTasks.remove(r);
        if (timeoutTask != null) {
            timeoutTask.cancel(false);
        }
    }

    // Timeout task to interrupt threads
    class TimeoutTask implements Runnable {

        private final Thread thread;

        public TimeoutTask(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            thread.interrupt();
        }
    }
}
登录后复制

用法:

要使用 TimeoutThreadPoolExecutor,您可以简单地用超时值实例化它:

TimeoutThreadPoolExecutor executor = new TimeoutThreadPoolExecutor(
    4, // corePoolSize
    8, // maximumPoolSize
    1, // keepAliveTime
    TimeUnit.SECONDS, // timeUnit
    new LinkedBlockingQueue<>(), // workQueue
    5, // timeout
    TimeUnit.SECONDS // timeoutUnit
);
登录后复制

然后,将任务提交给执行者通常:

executor.submit(() -> {
    // long-running task
});
登录后复制

如果任务花费的时间超过指定的超时时间,执行任务的线程将被中断,导致任务正常终止。

替代解决方案

实现任务超时的另一种方法是使用响应中建议的 ScheduledExecutorService 。这涉及将任务作为 Callable 提交并保留创建的 future。然后可以安排第二个任务在一段时间后取消未来,从而有效地中断任务。

以上是如何在 ExecutorService 中实现可中断任务的超时?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板