Java线程分为用户线程和守护线程。
注意:
package constxiong.concurrency.a008;
/**
* 测试守护线程
* @author ConstXiong
* @date 2019-09-03 12:15:59
*/
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
结论:
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