dab*_*aba 0 java concurrency multithreading
感觉自己的java并发知识越来越生疏了,想弄清楚为什么线程池不接受以下代码中的更多任务:
ExecutorService e = Executors.newFixedThreadPool(aNumber);
// Task 1
for (int i=0; i<n; i++)
e.submit(new aRunnable());
while (!e.isTerminated());
System.out.println("Task 1 done");
// Task 2
for (int i=0; i<n; i++)
e.submit(new anotherRunnable());
while (!e.isTerminated());
System.out.println("Task 2 done");
Run Code Online (Sandbox Code Playgroud)
它永远不会启动任务 2,当任务 1 中的最后一个任务运行时,线程“冻结”,就像它在等待其他任务完成一样。
怎么了?
它永远不会启动任务 2,当任务 1 中的最后一个任务运行时,线程“冻结”,就像它在等待其他任务完成一样。
它在等待。 ExecutorService.isTerminated()在线程池关闭后等待线程池任务完成。由于您从未调用过,e.shutdown();您的循环将永远旋转。引用ExecutorServicejavadocs:
如果关闭后所有任务都已完成,则返回 true。请注意,除非先调用 shutdown 或 shutdownNow,否则 isTerminated 永远不会为真。
你没有关闭服务,所以这永远不会是真的。一般来说,任何while像这样在循环中旋转的东西都是反模式——至少Thread.sleep(10);在循环中放了一个。通常我们会e.awaitTermination(...)再次使用,这只是在您调用e.shutdown();. 并且您不想关闭它ExecutorService,因为您将向它提交更多任务。
如果您想等待所有任务完成然后提交更多任务,我会执行以下操作并调用从第一批提交任务返回get()的Futures。就像是:
List<Future> futures = new ArrayList<Future>();
for (int i = 0; i < n; i++) {
futures.add(e.submit(new aRunnable()));
}
// now go back and wait for all of those tasks to finish
for (Future future : futures) {
future.get();
}
// now you can go forward and submit other tasks to the thread-pool
Run Code Online (Sandbox Code Playgroud)