请看这个例子。我从我的生产项目中获取它。 Web 服务器接收命令并启动新线程,该线程通过 TheadPool 开始计算。当用户想要结束计算时,他发送另一个命令来中断这个新线程,ThreadPool 的工作人员正在关闭。它工作正常,但我不明白为什么。
public static void main(String[] args) throws Throwable {
final ExecutorService p = Executors.newFixedThreadPool(2);
System.out.println("main say: Hello, I'm Main!");
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " say: Starting monitor");
Thread monitor = new Thread(new Runnable() {
@Override
public void run() {
try {
while(true) {
Thread.sleep(1500);
System.out.println(Thread.currentThread().getName() + " say: I'm still here...hahahahah");
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: Bye for now!");
}
}
},"monitor");
monitor.setDaemon(true);
monitor.start();
List<Callable<Integer>> threads = new ArrayList<>();
for (int i = 0; i < 5; i++) {
threads.add(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
System.out.println(Thread.currentThread().getName() + " say: Hello!");
try {
for (int c = 0; c < 5; c++) {
System.out.println(Thread.currentThread().getName() + " say: " + c);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: I'm interrupted :(");
}
System.out.println(Thread.currentThread().getName() + " say: Bye!");
return 0;
}
});
}
System.out.println(Thread.currentThread().getName() + " say: Starting workers");
try {
p.invokeAll(threads);
} catch (InterruptedException e) {
System.out.println(Thread.currentThread().getName() + " say: I'm interrupted :(");
}
System.out.println(Thread.currentThread().getName() + " say: Bye!");
}
}, "new thread");
System.out.println("main say: Starting new thread");
t.start();
System.out.println("main say: Waiting a little...");
Thread.sleep(1250);
System.out.println("main say: Interrupting new thread");
t.interrupt();
// p.shutdown();
System.out.println(String.format("main say: Executor state: isShutdown: %s, isTerminated: %s",
p.isShutdown(),
p.isTerminated()));
System.out.println("main say: Bye...");
}
主要问题:当 currentThread 中断时,为什么 ThreadPool 会中断它的 worker?我在哪里可以了解它的行为?
为什么在这个例子中主线程不退出,但什么都不做? ThreadPool 处于非 Activity 状态但不是 isTerminated 和 isShutdown 并且不处理其余任务。
最佳答案
Main question: why does ThreadPool interrupts its workers, when currentThread interrupted? Where can I learn about this its behavior?
您过于笼统了。 ExecutorService
的invokeAll()
方法会在任务中断时取消所有未完成的任务。这记录在 the API docs 中.
如果您问“我怎么知道它会那样做”,那么文档就是您的答案。如果你问为什么接口(interface)是这样设计的,那么这是有道理的,因为当它被中断时,该方法抛出 InterruptedException
而不是返回一个值,因此可以合理地假设任何进一步那些未完成的任务可能执行的工作将被浪费。
And why in this example main thread don't exits, but do nothing?
“主线程”是在 main()
开始处启动的线程。此线程确实退出,并且在它退出之前它会做几件其他事情,包括创建、启动和中断线程,以及输出多条消息。它在控制到达 main()
的末尾时退出。
但也许你的意思是线程“新线程”直接由主线程启动。该线程还做几件事,包括启动监控线程和向执行程序服务提交作业。或者你可能会问为什么这个线程在 ExecutorService
工作时不退出,但是为什么它会在等待 invokeAll()
方法执行时退出返回?即使该方法返回 Future
的列表,其文档也清楚地表明它阻塞直到提交给它的所有任务都完成,或者发生异常。
关于java - 当线程中断时,为什么 ThreadPool 会中断其工作人员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37446732/