java 如果编译时任务计数未知,则执行器不会执行所有任务
java Executor not executing all tasks if task count is not known in compile time
我有一个非常简单的 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 队列中的对象计数,那么并非所有任务都将被执行。
这是一个非常奇怪的行为,对于 1-2 个 fixedThreadPool 线程它会起作用,但是对于 3 个及以上的固定线程通常只会执行 5-7 个任务。
问题是队列中的对象计数来自数据库,因此我无法将其硬编码到 for 循环中。
方法processRule做一些数据库inserts/selects 所以我也不想打开太多threads/connections, 4-5 SQL 同时选择就足够了。
预先感谢您提供的任何帮助如何 运行 所有任务以及如何 运行 4 并行并将所有其他任务(最多 300 个)放入执行程序队列。
编辑:抱歉忘了写在这段代码之后另外两行是 executor.shutdown() 并等待完成。
我假设你更换了
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()
在每次迭代中都是 re-evaluated。考虑初始队列大小为 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 调试器中单步执行代码,您会立即看到这一点。
我有一个非常简单的 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 队列中的对象计数,那么并非所有任务都将被执行。
这是一个非常奇怪的行为,对于 1-2 个 fixedThreadPool 线程它会起作用,但是对于 3 个及以上的固定线程通常只会执行 5-7 个任务。
问题是队列中的对象计数来自数据库,因此我无法将其硬编码到 for 循环中。
方法processRule做一些数据库inserts/selects 所以我也不想打开太多threads/connections, 4-5 SQL 同时选择就足够了。
预先感谢您提供的任何帮助如何 运行 所有任务以及如何 运行 4 并行并将所有其他任务(最多 300 个)放入执行程序队列。
编辑:抱歉忘了写在这段代码之后另外两行是 executor.shutdown() 并等待完成。
我假设你更换了
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()
在每次迭代中都是 re-evaluated。考虑初始队列大小为 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 调试器中单步执行代码,您会立即看到这一点。