首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果编译时不知道任务计数,java执行器就不会执行所有任务

如果编译时不知道任务计数,java执行器就不会执行所有任务
EN

Stack Overflow用户
提问于 2022-04-21 19:07:14
回答 1查看 109关注 0票数 0

我有一个非常简单的java代码片段:

代码语言:javascript
复制
  ExecutorService executor = null;          
      try {
          executor = Executors.newFixedThreadPool(4);             
          for (int i = 0; i < 10; i++) {                
              executor.submit( () -> processRule(rule_queue.poll()));           
            }
       }   

事情是这样的:如果我用rule_queue.size()替换10 (在我的例子中是rule_queue.size队列中的对象计数),那么并不是所有的任务都会被执行。

这是一种非常奇怪的行为,对于1-2个fixedThreadPool线程来说,它可以工作,但是对于3个或更高的固定线程,通常只执行5-7个任务。

问题是队列中的对象数量来自数据库,因此我无法将其硬编码到for循环中。

方法processRule执行一些数据库插入/选择,所以我也不想打开太多的线程/连接,同时选择4-5SQLSelects就足够了。

感谢您的帮助,如何运行所有任务,以及如何并行运行4,并将所有其他任务(最多可达300)放到执行者队列中。

编辑:抱歉,忘了写这段代码之后,另外两行是executor.shutdown(),等待完成。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-21 22:51:44

我猜你换了

代码语言:javascript
复制
for (int i = 0; i < 10; i++) {                
    executor.submit( () -> processRule(rule_queue.poll()));           
}

使用

代码语言:javascript
复制
for (int i = 0; i < rule_queue.size(); i++) {
//                  ^^^^^^^^^^^^^^^^^
    executor.submit( () -> processRule(rule_queue.poll()));           
}

问题是rule_queue.size()在每次迭代时都会被重新评估。考虑初始队列大小为2的情况。

代码语言:javascript
复制
Iteration    i   rule_queue.size()   result
---------    -   -----------------   ------
    1        0           2           submit
    2        1           1           exit loop

所以你的规则只有一半会被提交。你想要的是:

代码语言:javascript
复制
while(rule_queue.size() > 0) {
    executor.submit( () -> processRule(rule_queue.poll()));           
}

如果您在IDE调试器中执行了代码,您就会立即看到这一点。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71959743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档