java - ExecutorService.shutdown。当任务队列变空时如何关闭执行器?

标签 java threadpool

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Main
{
    public static void main(String[] args)
    {
        final ExecutorService executor = Executors.newFixedThreadPool(10);
        executor.execute(new Runnable()
        {
            @Override
            public void run()
            {
                for (int i = 0; i < 10; i++)
                    executor.execute(new Runnable()
                    {
                        @Override
                        public void run()
                        {
                             System.out.println("run");
                        }
                    });
            }
        });
        executor.shutdown();
        try
        {
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
    }
}

由于 shutdown 后调用内部 executor.execute,我收到 RejectedExecutionException。在这种情况下我该如何等待执行者?

最佳答案

您必须知道什么时候不再有任务。这不是它可以为你猜测的东西。将关闭移至第一个任务,它将按您的预期运行。即仅当您知道不会添加更多任务时才调用 shutdown。

另一种方法是使用

final ExecutorService executor = new ThreadPoolExecutor(0, 10, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

这不会关闭执行器,但会停止所有线程,当您不再需要执行器时,您可以丢弃它。注意:如果您稍后添加更多任务,它将根据需要启动线程。

final ThreadPoolExecutor executor = new ThreadPoolExecutor(10, 10, 100, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 1000; i++)
    executor.submit(new Callable<Void>() {
        @Override
        public Void call() throws Exception {
            Thread.sleep(2);
            return null;
        }
    });
while (executor.getQueue().size() > 0) {
    System.out.println("Queue " + executor.getQueue().size() + ", Pool size " + executor.getPoolSize());
    Thread.sleep(200);
}
executor.setCorePoolSize(0);
while (executor.getPoolSize() > 0) {
    System.out.println("Pool size " + executor.getPoolSize());
    Thread.sleep(200);
}
System.out.println("Pool size " + executor.getPoolSize());

打印

Queue 946, Pool size 10
Queue 32, Pool size 10
Pool size 10
Pool size 0

然后退出。注意:如果任何线程仍在运行,程序将不会退出。

关于java - ExecutorService.shutdown。当任务队列变空时如何关闭执行器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14670785/

相关文章:

java - 在所有线程完成之前从 java 方法返回

java - TheadFactoryBuilder生成的ThreadFactory线程安全吗?

java - 我可以在fixedThreadPool中使用静态LOGGER对象吗?

java - "Column Count doesn' t 第 1 行的匹配值计数"E

java - 在java中生成没有重复/排列的变体

java - 如何在android中扩展2个库类

java - 为什么 Hazelcast 很快?

java - tomcat 中有 100 个线程 TIMED_WAITING,导致它在线程总数超过 200 时停止

java - Springboot + MySQL + 找不到驱动类

java.lang.string类型的Java值无法转换为jsonobject