Java多线程编程之守护线程

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

  • 用户线程:直到自己运行完或者遇到异常就结束
  • 守护线程:生命周期伴随着用户线程,随着用户线程结束而结束。

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

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

 1 package com.my.day01.demo05;
 2 
 3 public class DaemoTest {
 4 
 5     public static void main(String[] args) {
 6         
 7         Thread t = new Thread(new Runnable() {
 8             
 9             @Override
10             public void run() {
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 package com.my.day01.demo05;
 2 
 3 public class DaemoTest {
 4 
 5     public static void main(String[] args) {
 6         
 7         Thread t = new Thread(new Runnable() {
 8             
 9             @Override
10             public void run() {
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 package com.my.day01.demo05;
 2 
 3 public class DaemoTest2 {
 4 
 5     public static void main(String[] args) {
 6 
 7         Thread t = new Thread(new Runnable() {
 8             @Override
 9             public void run() {
10 
11                 Thread tt = new Thread(new Runnable() {
12                     @Override
13                     public void run() {
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 main
2 Thread1running
3 Thread2running
4 Thread1done

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

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

main

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

总结:

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

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

猜你喜欢

转载自www.cnblogs.com/lymonk/p/12376068.html