Java执行人如果在编译时间中不知道任务计数,则不执行所有任务

发布于 2025-01-23 11:04:54 字数 592 浏览 0 评论 0原文

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

  ExecutorService executor = null;          
      try {
          executor = Executors.newFixedThreadPool(4);             
          for (int i = 0; i < 10; i++) {                
              executor.submit( () -> processRule(rule_queue.poll()));           
            }
       }   

这是:如果我替换10个(在我的情况下,使用rule_queue queue中的对象计数使用rule_queue.size.size(),那么并非所有任务都将被执行。

它是一个非常奇怪的行为,对于1-2个固定线程螺纹,它将起作用,但是对于3及以上的固定线程,通常只执行5-7个任务

。 t将其用于循环

中 运行所有任务以及如何并行运行4,然后将所有其他任务放在执行者队列中的所有任务(最多可达300)

。 。

I have a very simple java code snippet:

  ExecutorService executor = null;          
      try {
          executor = Executors.newFixedThreadPool(4);             
          for (int i = 0; i < 10; i++) {                
              executor.submit( () -> processRule(rule_queue.poll()));           
            }
       }   

And here is the thing: if I replace the 10 (which is in my case the count of objects in the rule_queue queue with rule_queue.size() then not all tasks will be executed.

It is a very strange behaviour, for 1-2 fixedThreadPool threads it will work, but for 3 and above fixed threads will usually be only 5-7 tasks executed.

The problem is the count of objects in the queue comes from the database so I can't hardcode it into the for loop.

The method processRule do some database inserts/selects so I also don't want to open too many threads/connections, 4-5 SQL Selects simultaneously would be sufficient.

Thanks in adavance for any help how to run all tasks and how to run 4 in parallel and put all the others (could be up to 300) to the executors queue.

Edit: sorry forgot to write that after this code two additional lines are executor.shutdown() and waiting for finish.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流年已逝 2025-01-30 11:04:54

我认为您被问题取代的

for (int i = 0; i < 10; i++) {                
    executor.submit( () -> processRule(rule_queue.poll()));           
}

for (int i = 0; i < rule_queue.size(); i++) {
//                  ^^^^^^^^^^^^^^^^^
    executor.submit( () -> processRule(rule_queue.poll()));           
}

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

Iteration    i   rule_queue.size()   result
---------    -   -----------------   ------
    1        0           2           submit
    2        1           1           exit loop

因此,只有一半的规则会提交。相反,您想要的是:

while(rule_queue.size() > 0) {
    executor.submit( () -> processRule(rule_queue.poll()));           
}

如果您在IDE调试器中介绍了代码,您将立即看到这一点。

I assume you replaced

for (int i = 0; i < 10; i++) {                
    executor.submit( () -> processRule(rule_queue.poll()));           
}

with

for (int i = 0; i < rule_queue.size(); i++) {
//                  ^^^^^^^^^^^^^^^^^
    executor.submit( () -> processRule(rule_queue.poll()));           
}

The problem is that rule_queue.size() is being re-evaluated at each iteration. Consider the case where the initial queue size is 2.

Iteration    i   rule_queue.size()   result
---------    -   -----------------   ------
    1        0           2           submit
    2        1           1           exit loop

So only half of your rules will be submitted. What you want instead is:

while(rule_queue.size() > 0) {
    executor.submit( () -> processRule(rule_queue.poll()));           
}

You would have immediately seen this if you had stepped through the code in your IDE debugger.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文