参考答案
Java线程分为用户线程和守护线程。
- 守护线程:是程序运行的时候在后台提供一种通用服务的线程。所有用户线程停止,进程会停掉所有守护线程,退出程序。
- Java中把线程设置为守护线程的方法:在 start 线程之前调用线程的 setDaemon(true) 方法。
注意:
- setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行。
- 守护线程创建的线程也是守护线程。
- 守护线程不应该访问、写入持久化资源,如文件、数据库,因为它会在任何时间被停止,导致资源未释放、数据写入中断等问题。
实例:
public class TestDaemonThread { public static void main(String[] args) { testDaemonThread(); } // public static void testDaemonThread() { Thread t = new Thread(() -> { //创建线程,校验守护线程内创建线程是否为守护线程 Thread t2 = new Thread(() -> { System.out.println("t2 : " + (Thread.currentThread().isDaemon() ? "守护线程" : "非守护线程")); }); t2.start(); //当所有用户线程执行完,守护线程会被直接杀掉,程序停止运行 int i = 1; while(true) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("t : " + (Thread.currentThread().isDaemon() ? "守护线程" : "非守护线程") + " , 执行次数 : " + i); if (i++ >= 10) { break; } } }); //setDaemon(true) 必须在 start() 之前设置,否则会抛出IllegalThreadStateException异常,该线程仍默认为用户线程,继续执行 t.setDaemon(true); t.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //主线程结束 System.out.println("主线程结束"); } }
结果:
t2 : 守护线程 t : 守护线程 , 执行次数 : 1 主线程结束 t : 守护线程 , 执行次数 : 2
结论:
- 上述代码线程t,未打印到 t : daemon thread , time : 10,说明所有用户线程停止,进程会停掉所有守护线程,退出程序。
- 当 t.start(); 放到 t.setDaemon(true); 之前,程序抛出IllegalThreadStateException,t 仍然是用户线程,打印如下:
Exception in thread "main" t2 : 非守护线程 java.lang.IllegalThreadStateException at java.lang.Thread.setDaemon(Thread.java:1359) at constxiong.concurrency.a008.TestDaemonThread.testDaemonThread(TestDaemonThread.java:39) at constxiong.concurrency.a008.TestDaemonThread.main(TestDaemonThread.java:11) t : 非守护线程 , 执行次数 : 1 t : 非守护线程 , 执行次数 : 2 t : 非守护线程 , 执行次数 : 3 t : 非守护线程 , 执行次数 : 4 t : 非守护线程 , 执行次数 : 5 t : 非守护线程 , 执行次数 : 6 t : 非守护线程 , 执行次数 : 7 t : 非守护线程 , 执行次数 : 8 t : 非守护线程 , 执行次数 : 9 t : 非守护线程 , 执行次数 : 10
以上,是Java面试题【什么是守护线程】的参考答案。
输出,是最好的学习方法。
欢迎在评论区留下你的问题、笔记或知识点补充~
—end—