CodeBlock-1:
public class DaemonThread {
public static void main(String[] args) {
System.out.println(Thread.currentThread().getName() + " is Starting");
Thread t = new Thread() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " is Starting");
try {
Thread.sleep(10_00);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is finished.");
}
};
// 设置为守护线程
t.setDaemon(true);
t.start();
try {
Thread.sleep(5_00);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " is finished.");
}
}
我们如上在main线程中定义了一个子线程t
,将子线程的run方法写为sleep调用比main方法的sleep调用更久时间,以验证父类线程main的执行完毕并释放对子线程有无影响。
控制台输出:
main is Starting
Thread-0 is Starting
main is finished.
Process finished with exit code 0//此代表所有线程执行完毕,并退出
由控制台可知,子线程中的System.out.println(Thread.currentThread().getName()+" is finished.");
语句并没能够得到执行,这是因为子线程比父线程sleep更久,在子类线程sleep期间,父类线程已执行完毕,子类线程没能再次在CPU中得到权限运行,被JVM关闭了线程。
CodeBlock-2: 此处将CodeBlock-2代码中的子线程设置为守护线程的代码注释掉。
// 设置为守护线程
// t.setDaemon(true);
控制台输出:
main is Starting
Thread-0 is Starting
main is finished.
Thread-0 is finished.
Process finished with exit code 0 //此代表所有线程执行完毕,并退出
此处子线程中的System.out.println(Thread.currentThread().getName()+" is finished.");
语句得到了执行,虽然子线程比父线程sleep更久,但是此时父类线程的消亡对子线程不产生影响,这样一来,子线程中的上述语句总是能够得到执行。
我们对于CodeBlock-2中的run语句内最后加上以下代码
while(true){
//donothing
}
在IDE的控制台,我们只能得到以下结果显示:
main is Starting
Thread-0 is Starting
main is finished.
Thread-0 is finished.
并没有显示Process finished with exit code 0
的提示,说明子线程 Thread-0一直在内存中运行,如果使用Jconsole可以看到。我们只能选择Console上的Stop Process 键来结束线程的运行,控制台会最后打上:Process finished with exit code -1
,表面有线程未执行完毕,被强制关闭了。