在所有线程完成之前从java方法返回
是否可以从在所有线程完成之前启动线程的java方法返回 这是我的密码:在所有线程完成之前从java方法返回,java,multithreading,thread-safety,threadpool,Java,Multithreading,Thread Safety,Threadpool,是否可以从在所有线程完成之前启动线程的java方法返回 这是我的密码: import java.util.concurrent.*; public class ExecutorSample { public static void main(String[] args) { ExecutorService service = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++)
import java.util.concurrent.*;
public class ExecutorSample {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
service.execute(() -> {
while (true) {
}
});
}
return;
}
}
import java.util.concurrent.*;
公共类执行器示例{
公共静态void main(字符串[]args){
ExecutorService=Executors.newCachedThreadPool();
对于(int i=0;i<10;i++){
service.execute(()->{
while(true){
}
});
}
返回;
}
}
因为我不明白的原因,这不会回来。为什么主线程的返回会受到工作线程被卡住的影响?您的
main
方法正在返回,但问题是JVM没有退出。您可以通过将main
方法重命名为其他方法来测试这一点,例如doMain()
,然后将main
编写为:
public static void main(String[] args) {
doMain();
System.out.printf("here");
}
您将看到您确实获得了输出,但程序并没有结束
所发生的事情是执行器。newCachedThreadPool使用,它创建非守护进程线程。当main
方法返回时,JVM将等待所有非守护进程线程完成(这就是它们与守护进程线程的区别——JVM不等待它们)。因为所有可运行程序都会永远运行,所以非守护进程线程永远不会完成,JVM也永远不会退出
你能做什么?一些选择:
- 使用重载,提供创建守护进程线程的线程工厂
- 在您的服务上使用。这将在每个正在运行的线程上发送一个中断。您仍然需要在每个线程上检查这一点,方法可以是调用抛出
的方法,或者显式调用InterruptedException
thread.currentThread().isInterrupted()
对于
shutdownNow
方法,请注意,仅中断线程本身并不足以停止它——在该线程上运行的代码必须通过检查其中断状态(使用这两种方法之一)并适当退出来进行协作。例如,您可以将while(true)
替换为while(!Thread.currentThread().isInterrupted())
你怎么知道这个方法没有返回?@khelwood我测试过了,它卡在了main上。@ScaryWombat Shutdownow也不起作用,因为这只是最好的尝试,实际上并没有关闭工人threads@Jessica你得给我们看看你的测试结果,也许是为什么有人否决了你。另外,您应该在代码示例中显示测试。将代码放在另一个方法中,从main
调用它,在另一个方法返回后,在main
中打印一些内容以测试其他方法是否返回。@yshavit从您的答案来看,似乎提供创建守护进程线程的线程工厂是更好的方法。这种方法有什么坏处吗?@Jessica:守护进程线程的坏处是,如果最后一个非守护进程线程退出,它们就没有机会清理了。不要将守护进程线程用于任何您关心以受控方式完成的事情。@NathanHughes Cool是否有java本机方式来构建此工厂?我试过guava ThreadFactoryBuilder,它很管用,但是使用本地java方式会更好,Jessica!我不知道有什么比guava的更好的方法来创建定制的线程工厂,或者只编写自己的线程工厂。创建线程并不难,而且Javadoc很有可能是不言自明的。(另外,谢谢你纠正了这个错误,@NathanHughes!)