当前位置: 首页 > 面试题库 >

JavaExecutorService在超时后中断任务

卞浩漫
2023-03-14
问题内容

我正在寻找可以提供超时的ExecutorService实现。如果提交到ExecutorService的任务花费的时间超过了超时时间,则这些任务将被中断。实现这样的野兽并不是一个困难的任务,但是我想知道是否有人知道现有的实现。

这是我根据以下一些讨论得出的。任何意见?

import java.util.List;
import java.util.concurrent.*;

public 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<Runnable, ScheduledFuture>();

    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;
    }

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

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

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

    @Override
    public void shutdown() {
        timeoutExecutor.shutdown();
        super.shutdown();
    }

    @Override
    public List<Runnable> shutdownNow() {
        timeoutExecutor.shutdownNow();
        return super.shutdownNow();
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        if(timeout > 0) {
            final 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);
        }
    }

    class TimeoutTask implements Runnable {
        private final Thread thread;

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

        @Override
        public void run() {
            thread.interrupt();
        }
    }
}

问题答案:

你可以为此使用ScheduledExecutorService。首先,你只提交一次即可立即开始,并保留创建的未来。之后,你可以提交新任务,该任务将在一段时间后取消保留的将来。

 ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); 
 final Future handler = executor.submit(new Callable(){ ... });
 executor.schedule(new Runnable(){
     public void run(){
         handler.cancel();
     }      
 }, 10000, TimeUnit.MILLISECONDS);

这将使你的处理程序(主要功能被中断)执行10秒钟,然后将取消(即中断)该特定任务。



 类似资料:
  • 我使用ExecutorService在超时后中断任务,为此我使用ScheduledExecutorService。首先,我提交的线程和它一次开始立即,并保留未来的创建。之后,我使用ScheduledExecutorService作为一个新任务,它将在一段时间后取消保留的future。 我已经实现了以下URL:ExecutorService中的解决方案,该解决方案在超时后中断任务,在超时之前它工作得

  • 我需要实现一个预定的执行器服务,它每隔x秒运行一个线程。线程执行应该中断,以防它需要超过y秒。我曾尝试使用SchduledExecutorService实现该解决方案,该解决方案具有可配置的间隔参数,但没有超时参数。我有一些想法,我想听听你对实现/技术的建议。

  • 问题内容: 我正在尝试以这种方式使用python的多处理程序包: 从池的进程中,我要避免等待等待60多个返回结果的进程。那可能吗? 问题答案: 这是一种无需更改功能即可执行此操作的方法。需要两个步骤: 使用您可以传递的选项来确保每次执行任务后重新启动池中的工作进程。 将现有的辅助函数包装在另一个函数中,该函数将调用守护程序线程,然后等待该线程的结果数秒钟。使用守护程序线程很重要,因为进程在退出之前

  • 如果http请求超时,我试图中断当前线程。我已经为Kafka事务设置了PlatformTransactionManager作为bean。我在方法级别使用@Transactional注释。我们将发布三个主题的信息。在第一个主题中发布消息后,我将添加线程。睡眠(5000),如果执行时间超过6秒,当前线程将从筛选器中断。所以这里的通话被打断了,但信息被发布给了Kafka。我们只是在传达信息。我们不消费任

  • 问题内容: 等待所有任务完成的最简单方法是什么?我的任务主要是计算,所以我只想运行大量的作业-每个内核上一个。现在,我的设置如下所示: 实现可运行。这似乎是正确执行的任务,但代码崩溃上用。这很奇怪,因为我玩了一些玩具示例,而且看起来很奏效。 包含数以万计的元素。我应该使用其他方法吗?我正在寻找尽可能简单的东西 问题答案: 最简单的方法是使用单行代码执行所需的操作。用你的话来说,你需要修改或包装以实

  • 我正在使用执行器服务并行运行任务。并行运行方法采用输入整数并返回整数 。由于并行任务具有返回类型,因此我使用了可调用的匿名类。您可以在下面的示例中看到 是从 executer 调用的。任务方法也有1秒的等待时间,并为抛出异常; 在下面的实现中,我使用invokeAll和isDone,并尝试收集数据。 下面的程序抛出。 未来任务迭代和检查有什么问题 isDone 和 get() 。如何处理特定调用的