Joh*_*ohn 1 java multithreading
切入正题简短回答---------------------
可以在此处找到演示已接受答案的代码:
完整示例:
https://github.com/NACHC-CAD/thread-example/tree/shutdown-first
执行:
原帖--------------------------------------
有许多使用 Java 线程和执行器的示例: https://www.baeldung.com/thread-pool-java-and-guava
https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html
https://howtodoinjava.com/java/multi-threading/java-thread-pool-executor-example/
https://jenkov.com/tutorials/java-concurrency/thread-pools.html
https://xperti.io/blogs/thread-pools-java-introduction/
https://www.journaldev.com/1069/threadpoolexecutor-java-thread-pool-example-executorservice
https://stackify.com/java-thread-pools/
但是,我无法成功编写一个执行所有任务、等待任务完成然后正确终止的示例。
从这个例子开始:https://howtodoinjava.com/java/multi-threading/java-thread-pool-executor-example/
该代码仅调用 executor.shutdown()。如果线程消耗任何时间,则不允许它们有时间完成。
我在这里创建了一个完整的最简单的示例:https ://github.com/NACHC-CAD/thread-example/tree/await-termination
仅关闭分支涵盖了此用例(https://github.com/NACHC-CAD/thread-example/tree/shutdown-only):
public void makeWidgets() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(batchSize);
log.info("Building " + howMany + " widgets...");
for (int i = 0; i < howMany; i++) {
Widget widget = new Widget(lotNumber, i);
WidgetRunnable runnable = new WidgetRunnable(widget);
executor.execute(runnable);
}
log.info("SHUTTING DOWN----------------");
executor.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
此代码给出以下输出(应该创建 1000 个小部件,并且它们应该在等待 1 秒后报告已完成)。
2022-04-23 21:27:05,796 21:27:05.796 [main] INFO (WidgetFactoryIntegrationTest.java:12) - Starting test...
2022-04-23 21:27:05,799 21:27:05.799 [main] INFO (WidgetFactory.java:29) - Building 100 widgets...
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-2] INFO (Widget.java:24) - Starting build: 1/1
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-4] INFO (Widget.java:24) - Starting build: 1/3
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-1] INFO (Widget.java:24) - Starting build: 1/0
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-5] INFO (Widget.java:24) - Starting build: 1/4
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-6] INFO (Widget.java:24) - Starting build: 1/5
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-7] INFO (Widget.java:24) - Starting build: 1/6
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-8] INFO (Widget.java:24) - Starting build: 1/7
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-10] INFO (Widget.java:24) - Starting build: 1/9
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-9] INFO (Widget.java:24) - Starting build: 1/8
2022-04-23 21:27:05,801 21:27:05.801 [main] INFO (WidgetFactory.java:35) - SHUTTING DOWN----------------
2022-04-23 21:27:05,800 21:27:05.800 [pool-1-thread-3] INFO (Widget.java:24) - Starting build: 1/2
2022-04-23 21:27:05,801 21:27:05.801 [main] INFO (WidgetFactoryIntegrationTest.java:18) - Done.
Run Code Online (Sandbox Code Playgroud)
如果我添加 executor.awaitTermination,代码将运行所有线程但永远不会终止。此示例位于等待终止分支中:https ://github.com/NACHC-CAD/thread-example/tree/await-termination
public void makeWidgets() {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(batchSize);
log.info("Building " + howMany + " widgets...");
for (int i = 0; i < howMany; i++) {
Widget widget = new Widget(lotNumber, i);
WidgetRunnable runnable = new WidgetRunnable(widget);
executor.execute(runnable);
}
try {
executor.awaitTermination(1000, TimeUnit.HOURS);
} catch(Exception exp) {
throw(new RuntimeException(exp));
}
log.info("SHUTTING DOWN----------------");
executor.shutdown();
}
Run Code Online (Sandbox Code Playgroud)
此代码让所有可运行程序完成但永远不会退出。如何让所有可运行程序完成并使代码运行完成(退出)?
参考ThreadPoolExecutor文档。waitTermination() 方法描述如下:
在关闭请求后阻塞,直到所有任务完成执行
shutdown() 方法描述如下
启动有序关闭,执行先前提交的任务,但不会接受新任务
这表明awaitTermination()调用在shutdown()调用之后有效。
为了解决上述问题,需要先调用shutdown(),然后调用awaitTermination()
注意:我没有亲自测试过这一点;然而,正如原帖评论中提到的,约翰已经这样做了,并且该机制有效
| 归档时间: |
|
| 查看次数: |
558 次 |
| 最近记录: |