【发布时间】:2021-08-23 09:40:56
【问题描述】:
我正在尝试掌握 Java 的并发性,我编写了这个简单的代码来打印字母表中的字母:
public static void main(String[] args) throws IOException, InterruptedException, ExecutionException {
final ExecutorService threadPool = Executors.newFixedThreadPool(4);
final ExecutorCompletionService<Character> completionService = new ExecutorCompletionService<>(threadPool);
final List<Character> letters = IntStream.range(65, 91).mapToObj(i -> (char) i).collect(Collectors.toList());
for (char letter : letters) {
completionService.submit(() -> printLetter(letter));
}
System.out.println("Starting shutdown");
threadPool.shutdown(); // I WAS EXPECTING CODE TO STOP HERE, WAITING FOR ALL THREADS COMPLETION
System.out.println("Ending shutdown");
}
private static char printLetter(char letter) {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Hello from: " + letter);
return letter;
}
当我执行上面的代码时,我希望代码在运行“threadPool.shutdown()”时等待先前线程的完成,但是它继续执行其余代码我可以在输出中看到:
Starting shutdown
Ending shutdown
Hello from: B
Hello from: D
....
Hello from: Z
而我想要的输出是:
Starting shutdown
Hello from: B
Hello from: D
....
Hello from: Z
Ending shutdown
我尝试使用 threadPool.awaitTermination(30, TimeUnit.SECONDS) 代替,但由于我忽略的原因,它等待完全完成 30 秒后再继续,即使所有字母都已打印.
如何等待所有线程完成?
【问题讨论】: