使用 ThreadPoolExecutor,allowCoreThreadTimeOut 和零核心线程有什么区别? [英] With ThreadPoolExecutor, what is the difference between allowCoreThreadTimeOut and zero core threads?

查看:118
本文介绍了使用 ThreadPoolExecutor,allowCoreThreadTimeOut 和零核心线程有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

阅读 ThreadPoolExecutor 的文档,我很困惑以下示例用法之间的区别:

Reading up on the documentation of ThreadPoolExecutor, I'm confused what the difference is between the following to example usages:

零核心线程和十个最大线程,其中后者在 2 秒后超时:

Zero core threads and ten max threads, of which the latter times out after 2 seconds:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
        0, // core threads
        10, // max threads
        2000, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(),
        Executors.defaultThreadFactory()
);

10 个核心线程和 10 个最大线程都在 2 秒后超时:

Ten core threads and ten max threads that both time out after 2 seconds:

ThreadPoolExecutor executor = new ThreadPoolExecutor(
        10, // core threads
        10, // max threads
        2000, TimeUnit.MILLISECONDS,
        new LinkedBlockingQueue<Runnable>(),
        Executors.defaultThreadFactory()
);

executor.allowCoreThreadTimeOut(true);

这些执行者的行为有什么不同吗?

Do these executors behave differently in any way?

推荐答案

可以阅读动机 这里.

我想要固定线程池之类的东西(Executors.newFixedThreadPool()) 但线程在它们闲置太久,再次需要时重新创建.

I want something like fixed thread pool (Executors.newFixedThreadPool()) but with threads dying off when they are idle for too long, and re-created when they are needed again.

最直观的方法 - 将核心大小设置为 0,将最大池大小设置为边界值,以及到 [无界队列] 的队列- 失败:根本没有执行任何任务(与 Javadoc 一致,但 - 恕我直言 - 有点违反直觉).

The most intuitive approach - set core size to 0, maximum pool size to the bounding value, and the queue to [an unbounded queue] - fails: no tasks get executed at all (consistently with Javadoc but - IMHO - a little bit counterintuitively).

executor.allowCoreThreadTimeOut(true); 可用于获取此行为.

如果指定corePoolSize = 0,为什么根本不执行任何任务的更多详细信息

More details why no tasks get executed at all if corePoolSize = 0 is specified

来自 Javadoc,

From the Javadoc,

使用无界队列(例如,没有预定义的容量)将导致新任务在队列中等待时所有 corePoolSize 线程都忙.因此,不超过 corePoolSize线程将永远被创建.(和maximumPoolSize 的值因此没有任何影响.)

Using an unbounded queue (for example a LinkedBlockingQueue without a predefined capacity) will cause new tasks to wait in the queue when all corePoolSize threads are busy. Thus, no more than corePoolSize threads will ever be created. (And the value of the maximumPoolSize therefore doesn't have any effect.)

因此,如果您指定 corePoolSize = 0 将不会创建任何线程,也不会执行任何任务.

Hence, if you specify corePoolSize = 0 no threads will ever be created, and no tasks will be executed at all.

然而,在实践中,当 corePoolSize 为零时,实现确实会创建一个线程(使用 Sun JDK6 和 OpenJDK11 进行测试).因此在实践中,任务执行,但创建的线程不会超过一个,而不管maximumPoolSize是什么.我不完全确定为什么,因为根据规范,它甚至不应该创建一个.

In practice, however, when the corePoolSize is zero, implementations does create one thread (tested with Sun JDK6 and OpenJDK11). So in practice, the tasks are executed, but no more than one thread is ever created, regardless of what maximumPoolSize is specified. I'm not entirely sure why because according to the spec, it shouldn't create even one.

下面是我的测试代码.这将只使用一个线程,但如果您指定 corePoolSize=10,它将使用 10.如果您添加 allowCoreThreadTimeOut(true),那么这些线程可能会超时.

Below is my test code. This will only ever use one thread, but if you specify corePoolSize=10, it will use 10. If you add allowCoreThreadTimeOut(true), then these threads can timeout.

LinkedBlockingQueue<Runnable> q = new LinkedBlockingQueue<Runnable>();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
        0, // core threads
        10, // max threads
        2, TimeUnit.MILLISECONDS,
        q
);

for (int i = 0; i < 10; i++) {
    final int j = i;
    executor.execute(() ->
        {
           try {
                   Thread.sleep(1000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           System.out.println(
               "TaskNo:" + j + ":" + Thread.currentThread().getName()
           );
         });
}

executor.shutdown();

这篇关于使用 ThreadPoolExecutor,allowCoreThreadTimeOut 和零核心线程有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆