简体   繁体   English

ExecutorService.shutDown()和ExecutorService.shutDownNow()之间的中间地带

[英]Middle ground between ExecutorService.shutDown() and ExecutorService.shutDownNow()

I currently have an ExecutorService where I want the following: 我目前有一个ExecutorService ,我想要以下内容:

  • No new tasks should be accepted. 不应接受任何新任务。
  • Current tasks should still keep on executing. 当前任务仍应继续执行。
  • All currently queued up tasks should be returned. 应返回所有当前排队的任务。

The issue I am facing is that the shutdown() will not return any non-executing submitted tasks (in fact it will wait until al tasks have been completed), while the shutdownNow() will abruptly try to kill all already existing tasks. 我面临的问题是shutdown()不会返回任何未执行的提交任务(事实上它会等到任务完成),而shutdownNow()将突然尝试杀死所有已经存在的任务。

How should I work around this? 我应该如何解决这个问题?

You should be able to accomplish this by creating your own class that extends ThreadPoolExecutor and providing your own shutdown method. 您应该能够通过创建自己的类来扩展ThreadPoolExecutor并提供自己的关闭方法来实现这一目标。

Below is an example for how this could be done, you might want to adjust it to your needs (providing more constructor methods for example) 下面是一个如何完成此操作的示例,您可能希望根据需要进行调整(例如,提供更多构造函数方法)

public class MyExecutor extends ThreadPoolExecutor {

    private final BlockingQueue<Runnable>   queue;

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

    public List<Runnable> shutdownSpecial() {
        ArrayList<Runnable> queued = new ArrayList<>();
        queue.drainTo(queued);
        this.shutdown();
        return queued;
    }
}

You can do something like follows: 您可以执行以下操作:

As you know, ExecutorService ThreadPool implementations uses a BlockingQueue (bounded or unbounded queue) as a holder to keep your jobs (runnable). 如您所知,ExecutorService ThreadPool实现使用BlockingQueue(有界或无界队列)作为持有者来保存您的作业(可运行)。

So, considering your requirement you just have to do something like this: 所以,考虑到你的要求,你只需要做这样的事情:

yourWorkqueue.clear();

And after that, you can call 之后,你可以打电话

executor.shutdown();

AFAIK, the currently executing jobs would not be there in the Queue. AFAIK,当前正在执行的作业不在队列中。 So, the thread in the pool will keep on working on the jobs in hand while you will clear the Job Queue. 因此,当您清除作业队列时,池中的线程将继续处理手头的作业。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM