java - 动态扩展线程数的 Java ExecutorService
问题描述
我有一个工作单元列表,我想并行处理它们。每个单元工作 8-15 秒,完全计算时间,没有 I/O 阻塞。我想要实现的是ExecutorService
:
- 没有工作可做时实例化了零个线程
- 如果需要,可以动态扩展至 20 个线程
- 允许我一次添加所有工作单元(不阻止提交)
就像是:
Queue<WorkResult> queue = new ConcurrentLinkedDeque<>();
ExecutorService service = ....
for(WorkUnit unit : list) {
service.submit(() -> {
.. do some work ..
queue.offer(result);
);
}
while(queue.peek() != null) {
... process results while they arrive ...
}
我没有成功的尝试是:
- 使用 a
newCachedThreadPool()
创建太多线程 - 然后我使用了它的内部调用
new ThreadPoolExecutor(0, 20, 60L, SECONDS, new SynchronousQueue<>())
,但后来我注意到 submit() 由于同步队列而阻塞 - 所以我用过
new LinkedBlockingQueue()
,只是为了发现 ThreadPoolExecutor 只产生一个线程
我确信有官方实现来处理这个非常基本的并发用例。有人可以建议吗?
解决方案
最简单的方法是使用该方法
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
类Executors。这为您提供了一个简单的开箱即用解决方案。您获得的池将根据需要扩大和缩小。您可以使用处理核心线程超时等的方法进一步配置它
。ScheduledExecutorService 是 ExecutorService 类的扩展,是唯一一个开箱即用的可以动态扩展和收缩的类。
推荐阅读
- python - 将 .py 转换为 .html 文件
- ruby-on-rails - Rails 6:控制器帮助方法仍在 /app/helpers 文件夹中?
- nginx - nginx 文件服务器上的慢 apache 基准测试
- wordpress - 使用应用程序将订单从 Woocommerce webhook 导出到谷歌表格
- java - 相当于 RSA/None/OAEPWithSHA1AndMGF1Padding 和 PHP 中的充气城堡
- ansible - Ansible 查找格式
- postgresql - 可以使用 pglogical 将本地数据库迁移到 AWS RDS 吗?
- node.js - Socket.io“连接”事件随机触发多次
- mongodb - 如何使用 cloudrun 执行 mongodump 到 cloudstorage?
- flutter - 无法在flutter中下载Bloc Pattern的包