我有一个非常简单的java代码片段:
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(),等待完成。
发布于 2022-04-21 22:51:44
我猜你换了
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调试器中执行了代码,您就会立即看到这一点。
https://stackoverflow.com/questions/71959743
复制相似问题