Java的线程分为两种,一个是用户线程,一个是守护线程。守护线程守护的对象就是用户线程,当用户线程结束后,守护它的守护线程也就会结束。二者的本质基本是一样的,唯一区别在于何时结束。

用户线程:直到自己运行完或者遇到异常就结束

守护线程:生命周期伴随着用户线程,随着用户线程结束而结束。

举个例子:运行状态的日志线程一般为守护线程,它时时记录运行状态的日志,守护着系统的主线程。当主线程结束或出现异常结束后,记录日志的守护线程就没有必要在记录,随着主线程结束而结束。

在java中将用户线程变为守护线程,调用setDaemon方法。

1 packagecom.my.day01.demo05;2
3 public classDaemoTest {4
5 public static voidmain(String[] args) {6
7 Thread t = new Thread(newRunnable() {8
9 @Override10 public voidrun() {11
12 try{13
14 System.out.println(Thread.currentThread().getName()+" running");15 Thread.sleep(2000);16 System.out.println("test");17 System.out.println(Thread.currentThread().getName()+" done");18
19 } catch(InterruptedException e) {20
21 e.printStackTrace();22 }23 }24 });25 //设置为非守护线程,随着main线程的结束,守护线程也结束
26 t.setDaemon(false);27 t.start();28
29 System.out.println(Thread.currentThread().getName());30 }31
32 }

结果为:

main

Thread-0 running

test

Thread-0 done

在这个例子中,线程t为非守护线程,那么在main线程执行完后,线程t仍在执行。从输出的结果就可以看出来。

将线程t设为守护线程再来看一下

1 packagecom.my.day01.demo05;2
3 public classDaemoTest {4
5 public static voidmain(String[] args) {6
7 Thread t = new Thread(newRunnable() {8
9 @Override10 public voidrun() {11
12 try{13
14 System.out.println(Thread.currentThread().getName()+" running");15 Thread.sleep(2000);16 System.out.println("test");17 System.out.println(Thread.currentThread().getName()+" done");18
19 } catch(InterruptedException e) {20
21 e.printStackTrace();22 }23 }24 });25 //设置为守护线程,随着main线程的结束,守护线程也结束
26 t.setDaemon(true);27 t.start();28
29 System.out.println(Thread.currentThread().getName());30 }31
32 }

结果为:

main

Thread-0 running

将线程设置为守护线程后,可以看到线程t没有运行完毕就随着main线程的结束而结束了。

再来看嵌套线程的守护线程,在main函数里面声明了一个名字叫Thread1的线程,在Thread1线程里面定义了一个名字为Thread2的线程。先将这个两个线程设为非守护线程,看结果。

1 packagecom.my.day01.demo05;2
3 public classDaemoTest2 {4
5 public static voidmain(String[] args) {6
7 Thread t = new Thread(newRunnable() {8 @Override9 public voidrun() {10
11 Thread tt = new Thread(newRunnable() {12 @Override13 public voidrun() {14 System.out.println(Thread.currentThread().getName() + "running");15 try{16 Thread.sleep(20_000);17 } catch(InterruptedException e) {18
19 e.printStackTrace();20 }21 System.out.println(Thread.currentThread().getName() + "done");22 }23
24 }, "Thread2");25
26 tt.setDaemon(false);27 tt.start();28
29 System.out.println(Thread.currentThread().getName() + "running");30 try{31
32 Thread.sleep(10_000);33
34 } catch(InterruptedException e) {35 e.printStackTrace();36 }37 System.out.println(Thread.currentThread().getName() + "done");38 }39 }, "Thread1");40
41 //设置为非守护线程,随着main线程的结束,守护线程也结束
42 t.setDaemon(false);43 t.start();44
45 System.out.println(Thread.currentThread().getName());46
47 }
48 }

结果:

main

Thread1running

Thread2running

Thread1done

Thread2done

main线程执行完后,Thread2和Thread1交替执行。再来看看将子线程Thread2设为守护线程,输出的结果为

1 main2 Thread1running3 Thread2running4 Thread1done

可以看到子线程Thread2守护Thread1,当Thread1结束后,Thread2也随之结束。

如果将线程Thread1也设置为守护线程,再来看结果

main

Thread1守护的是main线程,main线程一结束Thread1也随之结束。Thread1的子线程Thread2也跟着结束(这就是说守护线程具有继承性,如果一个线程为守护线程,那么它的子线程都为守护线程)

总结:

1.守护线程守护的是它所在声明的那个线程。

2.当指定一个线程为守护线程后,它的子线程都是守护线程。