守护线程

守护线程

作用:给用户线程提供服务

在Java中有两类线程: User Thread(用户线程)、Daemon Thread(守护线程),分类标准是线程是否会阻止JVM的停止——只要当前JVM实例中尚存在任何一个非守护线程没有结束,守护线程就全部继续工作;只有当最后一个非守护线程结束时,所有守护线程才会随着JVM一同结束工作。(非守护线程等同于用户线程)

我们知道,Java虛拟机通常会继续执行线程,直到发生以下两种中的任一情况时,Java程序才能运行结束:

1.已调用System.exit()方法
2.所有非守护程序线程的线程都已结束

而一般情况下我们不会调用System.exit()方法,所以大部分的Java程序的结束都是由于所有用户线程都结束而导致的。

所以可以认为,任何一个守护线程都是整个JVM中所有用户线程(非守护线程)的管家。Daemon的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC(垃圾回收器),它是一个很称职的守护者。

守护线程的特性

线程类型默认继承自父线程

守护线程创建的线程为默认是守护线程,同样,用户线程创建的线程默认为用户线程。非守护线程如果想创建一个守护线程,需要调用Thread.setDaemon来设置它(Thread类用布尔值daemon属性来表示线程是否是守护线程), 并且,该方法必须在start之前调用,否则会抛出 IllgalThreadStateException 异常。

被谁启动?

通常由JVM启动,而不是由用户去启动。当JVM启动时,通常会有一个非守护线程(通常为执行main函数的线程)。

不影响JVM退出

当只剩下守护线程时,JVM就会退出,因为如果只剩下守护线程,就没必要继续运行程序了。

守护线程没结束并不会影响JVM的正常停止:假设所有用户线程都结束了,那么就算有5个守护线程正在运行,JVM也会正常停止:

守护线程和普通线程的区别

User和Daemon两者几乎没有区别,唯一的不同之处就在于虚拟机的离开:如果User Thread已经全部退出运行了,只剩下Daemon Thread存在了,虚拟机也就退出了,这是因为没有了“被守护者”,Daemon也就没有工作可做了,也就没有继续运行程序的必要了。

这就是守护线程的作用:告诉JVM不需要等待它退出,当JVM中所有的线程都是守护线程的时候,JVM就可以正常的退出了。

我们是否需要给线程设置为守护线程?

我们通常不应把自己的线程设置为守护线程,因为设置为守护线程是很危险的。比如线程正在访问如文件、数据库的时候,所有用户线程都结束了,那么守护线程会在任何时候甚至在一个操作的中间发生中断,所以守护线程永远不应该去访问固有资源。

代码案例:

定义三个线程类,分别是ThreadA,ThreadB, ThreadC。 继承Thread类,重写run()方法,在方法中循环输出线程名称以及执行次数。其中ThreadA、ThreadB为用户线程,循环输出5次。ThreadC为守护线程,循环输出20次(次数太少无法观察到效果,可以增加循环次数,例如循环输出50次,100次等)。

主方法中创建线程对象,使用setDaemon(true)设置ThreadC的对象为守护线程,然后调用start()方法启动线程(注意,setDaemon()需要在start()方法启动线程前设置)。观察输出结果。

线程是随机执行,可以多运行几次,查看不同的输出结果。

输出结果:

示例一:

当用户线程执行结束后,守护线程也结束执行。(注意:当用户线程执行结束后,守护线程不是立即停止执行,其中有一段缓冲时间,所以守护线程还输出了5次。)

示例二:

当用户线程执行结束后,守护线程还没有开始执行就已经结束执行,所以守护线程一次都没有输出。

 

 

Java

线程池——治理线程的最大法宝

2020-8-9 21:23:13

Java

自动创建线程池的风险

2020-8-11 19:36:11

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索