

面试准备不充分,被Java守护线程干懵了,面试官主打一个东西没用但你得会 - JavaBuild
source link: https://www.cnblogs.com/JavaBuild/p/18062883
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

面试官:小伙子请聊一聊Java中的精灵线程?
我:什么?精灵线程?啥时候精灵线程?
面试官:精灵线程没听过?那守护线程呢?
我:守护线程知道,就是为普通线程服务的线程嘛。
面试官:没了?守护线程的特点,怎么使用,需要注意啥,Java中经典的守护线程都有啥?
我:不知道。。。
这的天,面试一个10K的工作,上来先整个精灵线程,直接把人整蒙了,难道提及Java多线程的时候,问的不应该是线程、线程池、并发冲突解决方案、如何加锁,以及各种锁的知识点吗?上来整个偏门的守护线程,这是出心的不想要啊。
何为守护线程
上面这段内容是在牛客上看到的,说实话这位面试官问的这内容确实主要一个:东西没用,但你得知道!可如果说他问的真是离谱吗?也算不上,精灵线程我们很少听到,但守护线程我们在学习Java线程的时候肯定有所耳闻!那么今天我们就一起来小酌一下这个 “ 守护线程
”
Java中的线程分为2种:用户线程和守护线程
用户线程又叫普通线程,是我们驱动业务逻辑运转的核心;而守护线程,顾名思义,是守护用户线程的一种线程,运行在后台提供通用服务,因此也叫后台线程或者精灵线程。
守护线程的使用场景
那在Java中这个守护线程都有什么实际用处,或者说应用场景呢?
- GC垃圾回收线程:这是JVM中非常经典的一个守护线程,它始终以低级别状态运行,用于实时监控和管理系统中的可回收资源,一旦我们的系统没有任何运行的用户线程时,程序也就不会再产生垃圾,这时,无事可做的垃圾回收线程会自动结束。
- 应用指标统计:部分服务可以通过守护线程来采取应用指标,服务结束则停止采集。
怎么设置守护线程
那我们在代码中,如何将一个线程设置为守护线程呢?咱们可以通过在 start 线程之前调用线程的 setDaemon(true) 方法,将一个线程设置为守护线程,来看一下下面的这个demo。
【代码实例1】
public class Test { public static void main(String[] args) { Thread thread1 = new Thread("守护线程"){ @Override public void run() { int i = 0; while (i <= 4){ i++; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+i); } super.run(); } }; Thread thread2 = new Thread("用户线程"){ @Override public void run() { int i = 0; while (i < 2){ i++; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+i); } super.run(); } }; //setDaemon, 不设置则默认false thread1.setDaemon(true);//设置thread1为守护线程 thread2.setDaemon(false);//设置thread2为普通线程 thread1.start(); thread2.start(); }}
输出:
守护线程:1用户线程:1用户线程:2守护线程:2
这段测试代码中,我们通过thread1.setDaemon(true)将线程1设置成了一个守护线程(false为普通线程),用户线程的循环次数为2,用户线程的循环次数为4,但当程序中的用户线程运行完之后,守护线程并没有继续向下循环,而是随着用户线程的结束而自我终止了。
守护线程的优先级
看到网上很多博文提到了守护线程的优先级问题,都说守护线程的优先级比较低,那我们通过一段测试用例看一下真实情况。
【代码实例2】
public class Test { public static void main(String[] args) { Thread thread1 = new Thread("守护线程"){ @Override public void run() { int i = 0; while (i <= 4){ i++; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+i+"-优先级:" +Thread.currentThread().getPriority()); } super.run(); } }; Thread thread2 = new Thread("用户线程"){ @Override public void run() { int i = 0; while (i < 2){ i++; try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+":"+i+"-优先级:" +Thread.currentThread().getPriority()); } super.run(); } }; //setDaemon, 不设置则默认false thread1.setDaemon(true);//设置thread1为守护线程 thread2.setDaemon(false);//设置thread2为普通线程 thread1.start(); thread2.start(); for (int i = 0; i <5 ; i++) { System.out.println("主线程:"+i+"-优先级:" +Thread.currentThread().getPriority()); } }}
输出:
主线程:0-优先级:5主线程:1-优先级:5主线程:2-优先级:5主线程:3-优先级:5主线程:4-优先级:5用户线程:1-优先级:5守护线程:1-优先级:5用户线程:2-优先级:5守护线程:2-优先级:5
这个测试结果是不是出乎意料?无论是主线程还是普通的用户线程,又或者说守护线程,他们的优先级都是5,优先级竟然都一样!
我们知道所谓的线程就是CPU 调度和分派的基本单位,根据优先级不同,来决定获取CPU时间片的先后顺序,因为主线程启动时,其他线程还没有启动,所以这时候它最先获得CPU调度权限;
又因为其他线程存在休眠时间,这个时间段上足够主线程执行完毕。主线程执行完后,用户线程和守护线程互相抢占CPU资源,交错执行,直至程序中没有普通线程为止!若没有休眠时间,且循环次数足够多时,我们可以看到主线程、守护线程、用户线程都竞争CPU时间片,呈现交错执行的结果!
在设置线程为守护线程的时候要注意一个事情,那就是当 start(); 放到 setDaemon(true); 之前,程序抛出IllegalThreadStateException。如下图:

原因是 setDaemon(true)源码中,有一个isAlive()的判断,判断当前线程的状态是否为活跃线程,若是则抛出异常,我们不能修改一个正在运行中的线程!
【源码解析1】
public final void setDaemon(boolean on) { checkAccess(); //线程已经启动后,不可修改,否则抛出非法线程状态异常 if (isAlive()) { throw new IllegalThreadStateException(); } daemon = on; }
OK,写到这里,关于守护线程的内容就讲完了,我们从什么是守护线程,守护线程的使用场景,优先级,注意事项等方面,进行了全面的介绍。
其实说实话,在我们日后工作中,很少直接使用上守护线程,所以它看似没那么重要,但在很多Java多线程相关的书籍中绝对都有提及,很多小伙伴在学习的过程中认为这个点不重要,也就相当然的忽略了,但遇到变态的面试官,专门挑拣一些偏僻的知识点考你时,难免陷入尴尬,所以希望借助这个考题,大家能够在日后更细心的学习哈。
如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!
Recommend
-
24
华为就孟晚舟事件声明:美国提交的证据材料不充分
-
31
以下为华为公司就孟晚舟事件的最新声明原文:大家早上好。我是BenjaminHowes,现任华为媒体事务副总裁。感谢各位对此案件的关注。今天我代表华为给大家做一个简短的声明,以帮助各位更好的理解华为的立场。出于对司法程序的尊重,我稍后不会回答问题。
-
40
我开过四台具有回火效果的车。但由于我本身不是一个发动机相关专业的汽车工程师,所以只能根据我现有的知…
-
24
相关新闻:过户逝者手机号需本人到场当事人拷问:死人能复生吗新浪科技讯7月23日下午消息,今日一段“过户逝者号码需双方本人到场”的视频引发网友热议。对此,中国移动通信集团江苏有限公司南京分公司回应称,当事人前往的是非指定营业厅,导致办理失败,
-
33
-
16
A型血人群更易感新冠病毒?专家:科学依据尚不充分
-
6
不充分的均衡:如何找到捡钱的机会人神共奋14分钟前是在均衡的系统规则中找到自己的位置 ,还是努力寻找少量“不充分”的市场机会,直面巨头?...
-
5
面试官:“我们在Java的集合和数据结构中都离不开比较器,请你聊一聊Comparable 和 Comparator 这两种的区别吧” 内心活动:“上来就这么直接吗,那些ArrayList,HashMap都不问呀,好,既然如此,那让我来征服你吧,面试官大人!” 我:“好滴!巴拉巴拉~”
-
6
在线程的生命周期中,不同状态之间切换时,可以通过调用sleep()、wait()、join()、yield()等方法进行线程状态控制,针对这一部分知识点,面试官们也会做做文章,比如问你这些方法的作用以及之间的区别。 那么今天我们就一起来总结一下这几个方法的作用及区别...
-
3
在之前的博文中,我们介绍了volatile关键字,Java中的锁以及锁的分类,今天我们花5分钟时间,一起学习一下另一个关键字:synchronized。 synchronized是什么? 首先synchronized是Java中的一...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK