如何强制立即终止ThreadPoolExecutor中的所有worker

时间:2012-10-10 14:29:10

标签: java multithreading threadpool threadpoolexecutor

我在TheadPoolExecutor内有很多任务。我的界面上有一个停止按钮,可以立即终止ThreadPoolExecutor内的所有线程。我正在寻找一种方法来做到这一点。 (没有shutDown()shutDownNow())。

由于

5 个答案:

答案 0 :(得分:11)

您无法立即安全地杀死线程。您的任务应该尊重中断并在中断时停止。如果您使用ThreadPoolExecutor.shutdownNow(),则所有正在运行的任务都将被中断。

唯一的选择是在一个单独的进程中的线程发出一个信号来杀死进程。

答案 1 :(得分:6)

shutdown()只会使ThreadPoolExecutor拒绝所有新的提交任务,并从队列中删除(如果ThreadPool是无限队列执行程序)待处理任务。 shutdownNow()将完全相同,并且还会调用interrupt()的{​​{1}}方法。因此,在Thread方法中,您应该正确处理它:

run()

答案 2 :(得分:5)

旧问题,但我认为您可以扩展ThreadPoolExecutor以捕获beforeExecute()中正在运行的Thread引用。 当调用shutdownNow()时,你可以stop()所有正在运行的Threads。 虽然我强烈建议您在任务中依赖isInterrupted()。

示例代码 - >

public class KillableThreadPoolExecutor extends ThreadPoolExecutor {

    private final Map<Runnable, Thread> executingThreads;

    public KillableThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, String threadNamePrefix) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, new YoungMemorySafeLinkedBlockingQueue<Runnable>(), ThreadFactories.create(threadNamePrefix));
        executingThreads = new HashMap<>(maximumPoolSize);
    }

    @Override
    protected synchronized void beforeExecute(Thread t, Runnable r) {
        super.beforeExecute(t, r);
        executingThreads.put(r, t);
    }

    @Override
    protected synchronized void afterExecute(Runnable r, Throwable t) {
        super.afterExecute(r, t);
        if(executingThreads.containsKey(r)) {
            executingThreads.remove(r);
        }
    }

    @Override
    public synchronized List<Runnable> shutdownNow() {
        List<Runnable> runnables = super.shutdownNow();
        for(Thread t : executingThreads.values()) {
            t.stop();
        }
        return runnables;
    }
}

答案 3 :(得分:2)

ThreadPoolExecutor is an ExecutorService. You can't stop all threads in ExecutorService either with shutdown() or shutdownNow() methods. You have to call shutdown(), awaitTermination() and shutdownNow() methods in a sequence for graceful shutdown as quoted by oracle documentation page

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

Other options:

  1. invokeAll()
  2. CountDownLatch
  3. Iterate through all Future.get() for all Callable tasks to achieve the same purpose.

答案 4 :(得分:1)

如果您可以在线程中使用Callable而不是Runnable,则可以尝试拨打someTask.cancel()以摆脱shutdownNow()时正在运行的任务调用

请注意,我没有尝试过这个,所以我不能保证它会像你想的那样工作,但从javadoc描述判断它值得一试。