【发布时间】:2015-05-04 10:59:18
【问题描述】:
在下面的代码中:
class Worker extends Thread {
Thread t;
public Worker(Thread thread) {
t=thread;
}
public void run() {
try {
t.join();
} catch(InterruptedException e) {
System.out.println("Exception is thrown and caught");
}
System.out.println(Thread.activeCount());
System.out.print("|work|");
}
public static void main(String[] args) {
Thread t=Thread.currentThread();
Worker worker = new Worker(t);
worker.setDaemon(true);
worker.start();
System.out.println("Exit from main method");
}
}
由于 worker 是加入到 main() 线程上的守护线程,|work|永远不应该打印,因为用户线程 main() 首先完成,并且由于 worker 是一个守护线程,所以当 main() 线程死亡时它也会停止。 但是,我得到的输出如下: 退出主方法 1 |工作|
请为我澄清这个问题。
在多次执行程序后,我观察到以下不同的输出:
没有 Thread.sleep(1000) :
退出主方法 2
退出主方法 1 |工作|
退出主方法 2 |工作|
使用 Thread.sleep(1000) :
退出主方法 2 |工作|
退出主方法
注意第一个输出没有 sleep() 方法。 |工作|未打印,但线程数显示为 2。这是否意味着 main() 线程执行在 Thread.activeCount() 之后但 |work| 之前结束是印刷的?在第三个输出中似乎 main() 在执行这两个语句后结束。
现在,我没想到 Thread.activeCount() 会是 2,因为守护线程 worker 加入到用户线程 main() 上,这意味着当 Thread.activeCount() 执行时,只会有工作线程和没有 main() 线程。
【问题讨论】:
-
我认为守护线程的意义在于它们是安全的“松散”;他们不需要加入。
-
InterruptedException发生了吗? -
没有。它没。打印后程序正常终止|work|
-
你怎么知道的?使用该代码,您可能无法分辨。对于该异常,您有一个空的
catch块。 -
您的程序将在所有非守护线程执行完毕后退出。你说 t.start() 和一个 Sysout 紧随其后。我认为您的 main() 甚至在 t.join 发生或发生某种调度之前就退出了,这使您的 Sysout 在 join 调用之前执行。你能执行几次(很多),看看如果你的行为改变了怎么办?在 t.start() 之后和 sysout 之前添加一个睡眠,看看会发生什么?
标签: java multithreading join daemon