不可能制作一个有大小限制的缓存线程池吗?

2023-12-07

似乎不可能创建一个限制其可以创建的线程数量的缓存线程池。

这是静态的Executors.newCachedThreadPool在标准Java库中实现:

 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?或者也许这是故意的?或者还有其他办法吗?

编辑:我想要与缓存线程池完全相同的东西(它按需创建线程,然后在超时后杀死它们),但它可以创建的线程数量受到限制,并且能够在完成后继续对其他任务进行排队达到其线程限制。根据sjlee的回应这是不可能的。看着execute()的方法ThreadPoolExecutor这确实是不可能的。我需要子类化ThreadPoolExecutor并覆盖execute()有点像SwingWorker确实如此,但是什么SwingWorker确实在其execute()是一个完整的黑客。


The 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

Addendum:这是一个相当古老的答案,似乎 JDK 在核心大小为 0 时改变了其行为。从 JDK 1.6 开始,如果核心大小为 0 并且池没有任何线程,ThreadPoolExecutor 将添加一个线程执行该任务。因此,核心大小 0 是上述规则的一个例外。谢谢Steve for bringing这引起了我的注意。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不可能制作一个有大小限制的缓存线程池吗? 的相关文章

随机推荐

  • 如何(准确)估计剩余下载时间?

    当然 您可以将剩余文件大小除以当前下载速度 但如果您的下载速度波动 而且它会波动 这不会产生非常好的结果 有什么更好的算法可以产生更平滑的倒计时 An 指数移动平均线非常适合这个 它提供了一种平滑平均值的方法 以便每次添加新样本时 旧样本对
  • Java 8 原始流到集合的映射方法

    这两种流创建方法之间是否存在显着差异 在性能或最佳实践方面 int arr2 1 2 3 4 5 6 Arrays stream arr2 map in gt in 2 mapToObj in gt new Integer in colle
  • “原始字符串正则表达式”到底是什么以及如何使用它?

    来自 python 文档regex 关于 特点 解决方案是使用 Python 的原始字符串表示法来表示正则 表达模式 反斜杠不会以任何特殊方式处理 前缀为的字符串文字 r So r n 是一个两个字符的字符串 含有 and n while
  • p:graphicImage 的替代方案,它可以显示来自 byte[] 的图像并控制浏览器缓存

    似乎有一个错误p graphicimage使用更新功能时 通过加载一张图像value myController myStreamedContent 有效 但是当改变时myController myStreamedContent随后更新p g
  • CUDA 可以解决许多“小型/中型”线性系统

    关于我尝试使用 CUDA 加速的问题的一些背景信息 我有大量小型 中型相同尺寸的线性系统需要独立求解 每个线性系统都是方形的 实数的 稠密的 可逆的和非对称的 这些实际上是矩阵系统 因此每个系统看起来都像 AX B 其中 A X 和 B 是
  • 浏览器后退按钮不会清除旧的后备 bean 值

    我们使用 JSF2 我们有一个带有表单字段的页面 其中命令按钮链接到支持 bean 当我们访问表单页面 输入值并提交时 支持 bean 会收到正确的值并将其带到下一页 如果我按浏览器中的后退按钮 它将转到带有表单的上一页 如果我在表单中输入
  • 如何实现通用的max函数?

    我知道这是因为模板函数的返回类型与第一个参数 T 的返回类型相同 如何修改此模板 使其在所有情况下都能正确运行 include
  • EventEmitter类的清晰概念

    代码写入子组件 mycomponent ts import Component OnInit EventEmitter Output from angular core Component selector app mycomponent
  • 将 shell 变量传递给 JSON 请求以进行curl?

    让我们看下面的例子 curl i X POST H Content Type application json d jsonrpc 2 0 method Player Open params item false http example
  • 排序多维数组javascript

    我想对双精度的多维数组进行排序 该数组如下所示 1 2 2 3 5 6 8 9 我想按 X 值对其进行排序 并保持 x y 值配对 我在网站上搜索了多维排序 发现了类似的帖子these其中排序函数修改如下 location sort fun
  • 如何检查字符串是否可以转换为浮点数?

    首先 我的背景是需要将浮点文字 字符串 转换为浮点 双精度值的编译器编写者 过去 15 年我没有做过任何浮点编程 所以我很确定这是一个完全愚蠢的新手问题 double res errno 0 res strtod const char li
  • 如何设置TabHost背景颜色

    我需要帮助 我发现在 TabHost 中更改背景颜色很困难 原图 我需要修改背景颜色 如下图所示 我也在我的代码和 XML 中尝试了很多东西 但都失败了 我的代码如下 TabHost tabHost getTabHost Tab 1 Tab
  • 如何在C++中设置文件权限(跨平台)?

    我正在使用 C ofstream写出一个文件 我想将权限设置为只能由用户访问 700 在unix中 我想我可以发出一个system chmod 700 file txt 但我需要这段代码也能在 Windows 上运行 我可以使用一些Wind
  • 如何使用Robot Framework处理提示框?

    我使用 Robot Framework 和 Selenium2Library 进行网站测试自动化 在其中一种情况下 会出现一个提示框 类似于警报的弹出窗口 但其中有一个输入字段 请参阅例子在这里 要求一些文字 问题是 Robot Frame
  • FileSystemWatcher Changed 事件引发两次

    我有一个应用程序 我正在寻找一个文本文件 如果对该文件进行了任何更改 我正在使用OnChanged事件处理程序来处理事件 我正在使用NotifyFilters LastWriteTime但该事件仍然被解雇两次 这是代码 public voi
  • Java IOException - 流已关闭

    I get IOException 流已关闭 当我运行这个程序时 文本包含许多行数据 程序应该读取每一行 执行必要的功能并将输出写入新文件 我很困惑应该先关闭哪个作家以及在哪里 import java net import java io
  • 将键放在 gnuplot 中的多图下方

    正如标题所示 我想将图例放在多图下方 我只为其中一张图添加图例 因为所有图的线条样式都相同 我遇到的问题是 如果我添加密钥set key below 绘图本身会调整大小以适合画布内的 大 键 我宁愿保持地块的大小 我尝试将密钥添加为多图中的
  • 函数 .C -- 参数设置编译失败

    我目前正在学习在 R 中调用编译的 C 代码 昨天 我为无限 pi 系列创建了一个函数 当在 R 中运行时 它返回一个长度为 1 的数字向量 pi 效果很好 今天我正在研究一个输出可变长度数值向量的函数 即为用户定义的斐波那契序列计算的n
  • 调整最后一行的弹性项目的大小

    我的问题是我想要具有可变范围宽度的弹性盒 并且一切正常 但不是在最后一行 我希望所有子项都具有相同的维度 即使该行未充满子项 最后一行 products list position relative display flex flex fl
  • 不可能制作一个有大小限制的缓存线程池吗?

    似乎不可能创建一个限制其可以创建的线程数量的缓存线程池 这是静态的Executors newCachedThreadPool在标准Java库中实现 public static ExecutorService newCachedThreadP