一、概述
在看java线程相关的内容时,有一个 daemon thread 守护线程的概念,看方法注释内容,大意是:将此线程标记为守护线程或用户线程。当运行的所有线程都是守护线程时,Java虚拟机将退出。
-
- Marks this thread as either a daemon thread or a user thread.
- The Java Virtual Machine exits when the only threads running are all daemon threads.
二、守护线程理解
1、有这么一段代码:
- public static void main(String[] args) {
- Thread mainThread = Thread.currentThread();
- System.out.println(mainThread.getName() +" mainThread daemon :" + mainThread.isDaemon());
-
- Thread thread = new Thread(() -> {
- int res = new Random().nextInt(1000);
- try {
- Thread.sleep(res);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "==》》res=" + res);
- });
- thread.setDaemon(true);
- thread.start();
- System.out.println("daemon : " + thread.isDaemon());
- System.out.println(Thread.currentThread().getName() + "==》程序执行完毕!");
- }
2、 thread.setDaemon(true); 时,结果如下 (异步线程没有执行):
- main mainThread daemon :false
- daemon : true
- main==》程序执行完毕!
3、thread.setDaemon(false); 时,结果如下(异步线程有结果):
- main mainThread daemon :false
- daemon : false
- main==》程序执行完毕!
- Thread-0==》》res=102
4、结论:当前 thread.setDaemon(true); 时,通过控制台的输出,我们可以看到 当线程被设置为守护线程后,此时程序中没有正在执行的 非守护线程,程序就会执行结束 --- 异步线程比 main线程晚2秒执行,此时 main线程已经执行完毕。
三、总结
1、java中线程默认都是非守护线程,即 daemon = false ,可以通过 thread.setDaemon(true); 设置为守护线程。
2、thread.setDaemon(true) 必须在 thread.start() 之前设置,否则会抛出 IllegalThreadStateException 异常。
3、在使用 junit 单元测试时,会出现: 无论线程是否为 守护线程,异步线程都不会执行 --- 不确定啥问题, 估计是 junit 单元测试的问题 。
4、比如下面这段代码:子线程内容不会执行的!
- @Test
- public void daemonNotest() throws Exception{
- Thread unitTestThread = Thread.currentThread();
- System.out.println(unitTestThread.getName() +" unitTestThread daemon :" + unitTestThread.isDaemon());
-
- Thread thread = new Thread(() -> {
- int res = new Random().nextInt(1000);
- try {
- Thread.sleep(1000L);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "==》》res=" + res);
- });
- System.out.println("daemon : " + thread.isDaemon());
- thread.start();
- System.out.println(Thread.currentThread().getName() + "==》程序执行完毕!");
- }
5、多线程相关的测试,请 使用 main 方法,比较好!经验之谈,不确定 Junit 是啥原因导致不执行!