在所有线程完成之前从 java 方法返回
Returning from java method before all threads are done
是否可以从 java 方法 return 在所有线程完成之前启动线程?
这是我的代码:
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;
}
}
这不是 return 出于某种我不明白的原因。为什么主线程的return会被工作线程卡住?
您的 main
方法 正在 返回,但问题是您的 JVM 没有退出。您可以通过将 main
方法重命名为其他名称(例如 doMain()
,然后将 main
写为:
来对此进行测试
public static void main(String[] args) {
doMain();
System.out.printf("here");
}
你会看到你确实得到了输出,但程序并没有结束。
发生的事情是 Executors.newCachedThreadPool
使用 default thread factory,它创建了非守护进程线程。当您的 main
方法 returns 时,JVM 将等待所有非守护线程完成(这就是它们与守护线程的区别——JVM 不会等待那些线程)。因为你所有的 Runnables 运行 永远,非守护线程永远不会结束,JVM 永远不会退出。
你能做什么?部分选项:
- 使用重载
newCachedThreadPool(ThreadFactory)
,提供创建守护线程的 ThreadFactory
- 在您的 ExecutorService 上使用
shutdownNow()
。这将在每个 运行ning 线程上发送一个中断。您仍然需要在每个线程上检查它,方法是调用抛出 InterruptedException
的方法或显式调用 Thread.currentThread().isInterrupted()
.
对于 shutdownNow
方法,请注意单独中断一个线程 不足以 停止它 -- 该线程上的代码 运行ning必须通过检查其中断状态(使用这两种方法之一)并适当退出来进行合作。例如,您可以将 while(true)
替换为 while (!Thread.currentThread().isInterrupted())
。
是否可以从 java 方法 return 在所有线程完成之前启动线程?
这是我的代码:
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;
}
}
这不是 return 出于某种我不明白的原因。为什么主线程的return会被工作线程卡住?
您的 main
方法 正在 返回,但问题是您的 JVM 没有退出。您可以通过将 main
方法重命名为其他名称(例如 doMain()
,然后将 main
写为:
public static void main(String[] args) {
doMain();
System.out.printf("here");
}
你会看到你确实得到了输出,但程序并没有结束。
发生的事情是 Executors.newCachedThreadPool
使用 default thread factory,它创建了非守护进程线程。当您的 main
方法 returns 时,JVM 将等待所有非守护线程完成(这就是它们与守护线程的区别——JVM 不会等待那些线程)。因为你所有的 Runnables 运行 永远,非守护线程永远不会结束,JVM 永远不会退出。
你能做什么?部分选项:
- 使用重载
newCachedThreadPool(ThreadFactory)
,提供创建守护线程的 ThreadFactory - 在您的 ExecutorService 上使用
shutdownNow()
。这将在每个 运行ning 线程上发送一个中断。您仍然需要在每个线程上检查它,方法是调用抛出InterruptedException
的方法或显式调用Thread.currentThread().isInterrupted()
.
对于 shutdownNow
方法,请注意单独中断一个线程 不足以 停止它 -- 该线程上的代码 运行ning必须通过检查其中断状态(使用这两种方法之一)并适当退出来进行合作。例如,您可以将 while(true)
替换为 while (!Thread.currentThread().isInterrupted())
。