因为听到一个同学的面试题中有关于JAVA的守护线程,刚好我之前对守护线程也比较陌生,今天就花点时间一起探索下守护线程相关的知识。
一.守护线程:顾名思义,它的功能主要是守护,一般功能是在后台监督前台的线程。当JVM中不存在一般线程的时候,JVM的生命就终结了。
二.JAVA中的线程种类: 1.守护线程 2.非守护线程(一般用户线程)。
三.守护线程的优先级:极低,低到JVM自动可以将其结束。
四.守护线程的实现:线程的写法基本与一般线程一致,只是在XXX.start() 之前需要进行 XXX.setDaemon(true);
五.守护线程使用的注意点: .尽量不实现数据逻辑处理操作,文件读写操作。
六.守护线程的应用:JVM的垃圾收集器-----后台监督前台线程方面的应用。
七.守护线程和守护进程的区别:守护进程为操作系统层面的概念。通俗理解:一个进程有挂掉的风险,但如果我们想让这个进程一挂掉就重新启动,让人看着肯定是不合理的,这时候使用守护进程来监督该进程就比较好了。守护进程通过检查被监督进程的生存状态,来决定是否重新启动该进程,保证该进程一直运行。
八.具体代码示例:
a.这个例子中,一般线程结束生命周期后,因为jvm中仅存在守护线程,导致jvm结束,守护线程不再执行。
public class Test { public static void main(String[] args) { Thread damonthread=new Mydaemon("守护线程"); Thread orginthread=new Mydaemon("一般线程"); orginthread.start(); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } damonthread.setDaemon(true); damonthread.start(); System.out.println("主线程"); } } class Mydaemon extends Thread{ public Mydaemon(String name) { setName(name); } @Override public void run() { for(int i=0;i<100;++i){ try { Thread.sleep(100); System.out.println("我是 "+Thread.currentThread().getName()+" 我的坐标是 "+i); } catch (InterruptedException e) { e.printStackTrace(); } } }
我是 一般线程 我的坐标是 0
我是 一般线程 我的坐标是 1
我是 一般线程 我的坐标是 2
我是 一般线程 我的坐标是 3
我是 一般线程 我的坐标是 4
我是 一般线程 我的坐标是 5
我是 一般线程 我的坐标是 6
我是 一般线程 我的坐标是 7
我是 一般线程 我的坐标是 8
我是 一般线程 我的坐标是 9
我是 一般线程 我的坐标是 10
我是 一般线程 我的坐标是 11
我是 一般线程 我的坐标是 12
我是 一般线程 我的坐标是 13
我是 一般线程 我的坐标是 14
我是 一般线程 我的坐标是 15
我是 一般线程 我的坐标是 16
我是 一般线程 我的坐标是 17
我是 一般线程 我的坐标是 18
我是 一般线程 我的坐标是 19
我是 一般线程 我的坐标是 20
我是 一般线程 我的坐标是 21
我是 一般线程 我的坐标是 22
我是 一般线程 我的坐标是 23
我是 一般线程 我的坐标是 24
我是 一般线程 我的坐标是 25
我是 一般线程 我的坐标是 26
我是 一般线程 我的坐标是 27
我是 一般线程 我的坐标是 28
我是 一般线程 我的坐标是 29
我是 一般线程 我的坐标是 30
我是 一般线程 我的坐标是 31
我是 一般线程 我的坐标是 32
我是 一般线程 我的坐标是 33
我是 一般线程 我的坐标是 34
我是 一般线程 我的坐标是 35
我是 一般线程 我的坐标是 36
我是 一般线程 我的坐标是 37
我是 一般线程 我的坐标是 38
我是 一般线程 我的坐标是 39
我是 一般线程 我的坐标是 40
我是 一般线程 我的坐标是 41
我是 一般线程 我的坐标是 42
我是 一般线程 我的坐标是 43
我是 一般线程 我的坐标是 44
我是 一般线程 我的坐标是 45
我是 一般线程 我的坐标是 46
我是 一般线程 我的坐标是 47
我是 一般线程 我的坐标是 48
主线程
我是 一般线程 我的坐标是 49
我是 守护线程 我的坐标是 0
我是 一般线程 我的坐标是 50
我是 守护线程 我的坐标是 1
我是 一般线程 我的坐标是 51
我是 守护线程 我的坐标是 2
我是 一般线程 我的坐标是 52
我是 守护线程 我的坐标是 3
我是 一般线程 我的坐标是 53
我是 守护线程 我的坐标是 4
我是 一般线程 我的坐标是 54
我是 守护线程 我的坐标是 5
我是 一般线程 我的坐标是 55
我是 守护线程 我的坐标是 6
我是 一般线程 我的坐标是 56
我是 守护线程 我的坐标是 7
我是 一般线程 我的坐标是 57
我是 守护线程 我的坐标是 8
我是 一般线程 我的坐标是 58
我是 守护线程 我的坐标是 9
我是 一般线程 我的坐标是 59
我是 守护线程 我的坐标是 10
我是 一般线程 我的坐标是 60
我是 守护线程 我的坐标是 11
我是 一般线程 我的坐标是 61
我是 守护线程 我的坐标是 12
我是 一般线程 我的坐标是 62
我是 守护线程 我的坐标是 13
我是 一般线程 我的坐标是 63
我是 守护线程 我的坐标是 14
我是 一般线程 我的坐标是 64
我是 守护线程 我的坐标是 15
我是 一般线程 我的坐标是 65
我是 守护线程 我的坐标是 16
我是 一般线程 我的坐标是 66
我是 守护线程 我的坐标是 17
我是 一般线程 我的坐标是 67
我是 守护线程 我的坐标是 18
我是 一般线程 我的坐标是 68
我是 守护线程 我的坐标是 19
我是 一般线程 我的坐标是 69
我是 守护线程 我的坐标是 20
我是 一般线程 我的坐标是 70
我是 守护线程 我的坐标是 21
我是 一般线程 我的坐标是 71
我是 守护线程 我的坐标是 22
我是 一般线程 我的坐标是 72
我是 守护线程 我的坐标是 23
我是 一般线程 我的坐标是 73
我是 守护线程 我的坐标是 24
我是 一般线程 我的坐标是 74
我是 守护线程 我的坐标是 25
我是 一般线程 我的坐标是 75
我是 守护线程 我的坐标是 26
我是 一般线程 我的坐标是 76
我是 守护线程 我的坐标是 27
我是 一般线程 我的坐标是 77
我是 守护线程 我的坐标是 28
我是 一般线程 我的坐标是 78
我是 守护线程 我的坐标是 29
我是 一般线程 我的坐标是 79
我是 守护线程 我的坐标是 30
我是 一般线程 我的坐标是 80
我是 守护线程 我的坐标是 31
我是 一般线程 我的坐标是 81
我是 守护线程 我的坐标是 32
我是 一般线程 我的坐标是 82
我是 守护线程 我的坐标是 33
我是 一般线程 我的坐标是 83
我是 守护线程 我的坐标是 34
我是 一般线程 我的坐标是 84
我是 守护线程 我的坐标是 35
我是 一般线程 我的坐标是 85
我是 守护线程 我的坐标是 36
我是 一般线程 我的坐标是 86
我是 守护线程 我的坐标是 37
我是 一般线程 我的坐标是 87
我是 守护线程 我的坐标是 38
我是 一般线程 我的坐标是 88
我是 守护线程 我的坐标是 39
我是 一般线程 我的坐标是 89
我是 守护线程 我的坐标是 40
我是 一般线程 我的坐标是 90
我是 守护线程 我的坐标是 41
我是 一般线程 我的坐标是 91
我是 守护线程 我的坐标是 42
我是 一般线程 我的坐标是 92
我是 守护线程 我的坐标是 43
我是 一般线程 我的坐标是 93
我是 守护线程 我的坐标是 44
我是 一般线程 我的坐标是 94
我是 守护线程 我的坐标是 45
我是 一般线程 我的坐标是 95
我是 守护线程 我的坐标是 46
我是 一般线程 我的坐标是 96
我是 守护线程 我的坐标是 47
我是 一般线程 我的坐标是 97
我是 守护线程 我的坐标是 48
我是 一般线程 我的坐标是 98
我是 守护线程 我的坐标是 49
我是 一般线程 我的坐标是 99
Process finished with exit code 0
b.这个例子中告诉我们,由于守护线程的身份,他的写文件操作无法完成。
import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class DaemonFIle { public static void main(String[] args) { Thread daemon=new Thread(new File_deal_thread()); daemon.setDaemon(true); daemon.start(); System.out.println("主线程终结"); } } class File_deal_thread implements Runnable{ public void run() { File file=new File("haha.txt"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } try { FileOutputStream fos=new FileOutputStream(file,true); try { fos.write("我是守护线程写的...".getBytes()); } catch (IOException e) { e.printStackTrace(); } } catch (FileNotFoundException e) { e.printStackTrace(); } } }
分析:当一般线程执行完毕,由于jvm中仅存守护线程,守护线程生命被jvm终结。如果该线程不设置setDaemon(true),那么我们是可以看到文件生成的。