ala*_*eno 25 java concurrency multithreading executorservice
我将一堆可运行的对象放入ExecutorService:
// simplified content of main method
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i = 0; i < workerCount; i++) {
threadPool.execute(new Worker());
}
Run Code Online (Sandbox Code Playgroud)
我希望我的程序/流程在所有工人完成后立即停止.但根据我的日志,它需要另外20-30秒才能发生.工人们没有分配任何资源,事实上,他们现在什么都不做.
不要误会我的意思,这对我来说不是一个至关重要的问题,我只是想了解发生了什么,我想知道这是不是正常行为.
ysh*_*vit 28
Executors.newCachedThreadPool()使用Executors.defaultThreadFactory()它的ThreadFactory.defaultThreadFactory的javadocs说"每个新线程都是作为非守护线程创建的"(重点补充).因此,为其创建的线程newCachedThreadPool是非守护进程.这意味着它们会阻止JVM自然退出("自然地",我的意思是你仍然可以调用System.exit(1)或终止程序以使JVM停止).
应用程序完成的原因是每个线程在newCachedThreadPool超时内创建并在一段时间不活动后自行关闭.当最后一个关闭时,如果你的应用程序没有任何非守护程序线程,它将退出.
您可以(并且应该)ExecutorService通过shutdown或手动关闭shutdownNow.
另请参阅JavaDoc for Thread,其中讨论了守护进程.
我希望我的程序/流程在所有工人完成后立即停止.但根据我的日志,它需要另外20-30秒才能发生.工人们没有分配任何资源,事实上,他们现在什么都不做.
问题是你没有关闭你的ExecutorService.将所有作业提交到服务后,应该关闭服务,否则JVM将不会终止,除非其中的所有线程都是守护程序线程.如果您没有关闭线程池,那么与ExecutorService(如果不是守护进程)相关联的任何线程都将阻止JVM完成.如果您已将任何任务提交到缓存的线程池,则必须等待线程超时并在JVM完成之前获取.
ExecutorService threadPool = Executors.newCachedThreadPool();
for(int i = 0; i < workerCount; i++) {
threadPool.execute(new Worker());
}
// you _must_ do this after submitting all of your workers
threadPool.shutdown();
Run Code Online (Sandbox Code Playgroud)
将线程作为守护进程启动很可能不是您想要执行的操作,因为您的应用程序可能在任务完成之前停止,并且所有任务将在此时立即终止.我刚刚进行了快速审核,并且ExecutorService在我们的生产代码中使用了178次,其中只有2个是作为守护程序线程启动的.其余的都正常关闭.
如果您需要ExecutorService在应用程序退出时强制停止,则使用shutdownNow()正确处理线程中断标志的顺序.
基本上在 ExecutorService 上,您调用 shutdown() 然后调用 waitTermination():
ExecutorService taskExecutor = Executors.newFixedThreadPool(4);
while(...) {
taskExecutor.execute(new MyTask());
}
taskExecutor.shutdown();
try {
taskExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22510 次 |
| 最近记录: |