不可能使缓存的线程池具有大小限制吗?

Matt Crinklaw-Vogt:

限制缓存线程池的创建数量似乎是不可能的。

这是在标准Java库中实现static Executors.newCachedThreadPool的方式:

 public static ExecutorService newCachedThreadPool() {
    return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                  60L, TimeUnit.SECONDS,
                                  new SynchronousQueue<Runnable>());
}

因此,使用该模板继续创建固定大小的缓存线程池:

new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new SynchronusQueue<Runable>());

现在,如果您使用它并提交3个任务,一切都会好起来的。提交任何其他任务将导致拒绝执行异常。

试试这个:

new ThreadPoolExecutor(0, 3, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runable>());

将导致所有线程按顺序执行。即,线程池将永远不会产生多个线程来处理您的任务。

这是ThreadPoolExecutor的execute方法中的错误吗?还是这是故意的?还是有其他方法?

编辑:我想要的东西完全类似于缓存的线程池(它会按需创建线程,然后在超时后将其杀死),但是它可以创建的线程数受到限制,并且一旦有线程就可以继续排队其他任务达到其线程限制。根据sjlee的答复,这是不可能的。查看ThreadPoolExecutor的execute()方法确实是不可能的。我需要像SwingWorker一样子类化ThreadPoolExecutor并重写exe​​cute(),但是SwingWorker在execute()中所做的事情是一个完整的技巧。

sjlee:

ThreadPoolExecutor具有以下几种关键行为,这些问题可以解释您的问题。

提交任务后,

  1. 如果线程池尚未达到核心大小,它将创建新线程。
  2. 如果已达到核心大小,并且没有空闲线程,则它将任务排队。
  3. 如果已达到核心大小,则没有空闲线程,并且队列已满,它将创建新线程(直到达到最大大小)。
  4. 如果已达到最大大小,则没有空闲线程,并且队列已满,将启动拒绝策略。

在第一个示例中,请注意,SynchronousQueue本质上的大小为0。因此,当您达到最大大小(3)时,拒绝策略开始执行(#4)。

在第二个示例中,选择的队列是LinkedBlockingQueue,它的大小不受限制。因此,您将陷入行为2。

您实际上不能对缓存类型或固定类型进行太多修改,因为它们的行为几乎完全确定了。

如果要有一个有限的动态线程池,则需要使用正的核心大小和最大大小以及有限大小的队列。例如,

new ThreadPoolExecutor(10, // core size
    50, // max size
    10*60, // idle timeout
    TimeUnit.SECONDS,
    new ArrayBlockingQueue<Runnable>(20)); // queue with a size

附录:这是一个相当老的答案,并且看起来JDK更改了其行为,即核心大小为0。从JDK 1.6开始,如果核心大小为0并且该池没有任何线程,则ThreadPoolExecutor将添加一个执行该任务的线程。因此,核心大小0是上述规则的例外。感谢史蒂夫使这引起我的注意。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有依赖类型的字符串文字-不可能吗?

来自分类Dev

具有可选参数的类Init-不可能吗?

来自分类Dev

在SingleChildScrollView内没有ListView是不可能的吗?

来自分类Dev

没有参数的步骤定义不可能吗?

来自分类Java

带有ArrayList的NullPointerException-应该不可能吗?

来自分类Java

有多个限制的线程池

来自分类Java

Spring 3具有基于注释的映射的简单无扩展url映射-不可能吗?

来自分类Dev

WebSphere中有多个Web容器线程池-可能吗?

来自分类Dev

/proc 的大小不可能大

来自分类Dev

这个查询COUNT是不可能的吗?

来自分类Dev

标签页的返回不可能吗?

来自分类Dev

拦截文件流...不可能吗?

来自分类Dev

不可能使用vue-recaptcha-v3

来自分类Dev

python范围步长不可能使用枚举

来自分类Dev

不可能使JavaScript功能和新行

来自分类Dev

为什么当我为注册人命名时,asm有不可能的限制?

来自分类Dev

有可能使用shared_ptr的对象池模式吗?

来自分类Dev

在垒中同时具有传输级安全性和消息级安全性是不可能的吗?为什么?

来自分类Dev

如何在Java中动态调整缓存线程池的大小

来自分类Java

缓存的线程池如何重用现有线程

来自分类Dev

为什么不可能显式地默认具有volatile参数的副本构造函数?

来自分类Dev

具有动态SELECT的T-SQL函数(不可能)-改为用过程解决

来自分类Dev

没有指针就不可能在循环中构造实例吗?

来自分类Dev

汇编:[SI + CX] =地址大小的不可能组合

来自分类Java

是否有可能使线程自身死锁?

来自分类Dev

具有大小限制和最近最少使用(LRU)驱逐的JavaScript localStorage缓存

来自分类Dev

锈可能具有大小特征的多态吗

来自分类Dev

了解“不可能”

来自分类Dev

不可能的NullPointerException

Related 相关文章

  1. 1

    具有依赖类型的字符串文字-不可能吗?

  2. 2

    具有可选参数的类Init-不可能吗?

  3. 3

    在SingleChildScrollView内没有ListView是不可能的吗?

  4. 4

    没有参数的步骤定义不可能吗?

  5. 5

    带有ArrayList的NullPointerException-应该不可能吗?

  6. 6

    有多个限制的线程池

  7. 7

    Spring 3具有基于注释的映射的简单无扩展url映射-不可能吗?

  8. 8

    WebSphere中有多个Web容器线程池-可能吗?

  9. 9

    /proc 的大小不可能大

  10. 10

    这个查询COUNT是不可能的吗?

  11. 11

    标签页的返回不可能吗?

  12. 12

    拦截文件流...不可能吗?

  13. 13

    不可能使用vue-recaptcha-v3

  14. 14

    python范围步长不可能使用枚举

  15. 15

    不可能使JavaScript功能和新行

  16. 16

    为什么当我为注册人命名时,asm有不可能的限制?

  17. 17

    有可能使用shared_ptr的对象池模式吗?

  18. 18

    在垒中同时具有传输级安全性和消息级安全性是不可能的吗?为什么?

  19. 19

    如何在Java中动态调整缓存线程池的大小

  20. 20

    缓存的线程池如何重用现有线程

  21. 21

    为什么不可能显式地默认具有volatile参数的副本构造函数?

  22. 22

    具有动态SELECT的T-SQL函数(不可能)-改为用过程解决

  23. 23

    没有指针就不可能在循环中构造实例吗?

  24. 24

    汇编:[SI + CX] =地址大小的不可能组合

  25. 25

    是否有可能使线程自身死锁?

  26. 26

    具有大小限制和最近最少使用(LRU)驱逐的JavaScript localStorage缓存

  27. 27

    锈可能具有大小特征的多态吗

  28. 28

    了解“不可能”

  29. 29

    不可能的NullPointerException

热门标签

归档