上QQ阅读APP看书,第一时间看更新
1.15 守护线程
Java中有两种线程,一种是用户线程,也称非守护线程;另一种是守护线程。
什么是守护线程?守护线程是一种特殊的线程,当进程中不存在非守护线程时,则守护线程自动销毁。典型的守护线程就是垃圾回收线程,当进程中没有非守护线程了,则垃圾回收线程也就没有存在的必要,自动销毁。用一个比较通俗的比喻来解释一下“守护线程”,任何一个守护线程都可以看作整个JVM中所有非守护线程的“保姆”,只要当前JVM实例中有任何一个非守护线程没有结束(好比幼儿园中有小朋友),那么守护线程(也就是保姆)就要工作,只有当最后一个非守护线程结束时(好比幼儿园中没有小朋友了),守护线程(也就是保姆)才会随着JVM一同结束工作。守护Daemon线程的作用是为其他线程的运行提供便利服务,最典型的应用就是GC(垃圾回收器)。综上所述,当最后一个用户线程销毁了,守护线程会退出,进程也随之结束。
主线程main在本节中属于用户线程,凡是调用setDaemon(true)代码并且传入true值的线程才是守护线程。
创建项目daemonThread,文件MyThread.java代码如下:
package testpackage; public class MyThread extends Thread { private int i = 0; @Override public void run() { try { while (true) { i++; System.out.println("i=" + (i)); Thread.sleep(1000); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
文件Run.java代码如下:
package test.run; import testpackage.MyThread; public class Run { public static void main(String[] args) { try { MyThread thread = new MyThread(); thread.setDaemon(true); thread.start(); Thread.sleep(5000); System.out.println("我离开thread对象也不再打印了,也就是停止了!"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
图1-69 最后一个用户线程销毁守护线程也退出了
程序运行结果如图1-69所示。
要在执行start()方法之前执行setDaemon(boolean)方法,不然会出现异常,示例代码如下:
package test.run; import testpackage.MyThread; public class Run2 { public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); thread.setDaemon(true); } }
程序运行出现异常如下:
Exception in thread "main" java.lang.IllegalThreadStateException at java.lang.Thread.setDaemon(Thread.java:1275) at test.run.Run2.main(Run2.jva:9)