Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在所有线程完成之前从java方法返回_Java_Multithreading_Thread Safety_Threadpool - Fatal编程技术网

在所有线程完成之前从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++)

是否可以从在所有线程完成之前启动线程的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++) {
            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!)