守護線程與用戶線程
用戶線程:我們平常創建的普通線程。
守護線程:用來服務於用戶線程;不需要上層邏輯介入
java線程分為守護線程和非守護線程,當java jvm檢測主線程或其他子線程執行完之后,守護線程也會馬上停止執行,我們可以使用Thread.setDaemon(ture或false)來設置一個線程是守護線程還是非守護線程,默認為false,可以通過Thread.isDaemon()方法查詢該線程是否是守護線程
1:我們將用案例來告訴你守護線程和非守護線程的區別和用法,代碼如下,先設置其為守護線程。
public class DeamonThread { public static void main(String[] args) { //"DeamonThread::print"是java1.8調用靜態方法 Thread thread = new Thread(DeamonThread::print); thread.setDaemon(true); thread.start(); System.out.println("退出Main方法"); } public static void print() { int counter = 1; while (true) { try { System.out.println("Counter:" + counter++); Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
print()方法里面是一個while死循環,以上代碼輸出結果如下,只輸出一次便退出了while(true)循環。
退出Main方法 Counter:1:
2:如果我們將daemon設置為非守護線程,代碼如下。
thread.setDaemon(false);
這時候就不會退出while(true)循環了,會一直執行下去,結果如下:
退出Main方法 Counter:1 Counter:2 Counter:3 .......
總結:非守護線程其實就是守護線程的氧氣,如果氧氣沒了,守護線程也會跟着死掉。
當線程只剩下守護線程的時候,JVM就會退出;補充一點如果還有其他的任意一個用戶線程還在,JVM就不會退出。
使用它需要注意些什么?
- thread.setDaemon(true)必須在thread.start()之前設置,否則會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置為守護線程。
- 在Daemon線程中產生的新線程也是Daemon的。
- 守護線程不能用於去訪問固有資源,比如讀寫操作或者計算邏輯。因為它會在任何時候甚至在一個操作的中間發生中斷。
- Java自帶的多線程框架,比如ExecutorService,會將守護線程轉換為用戶線程,所以如果要使用后台線程就不能用Java的線程池。
意義及應用場景
當主線程結束時,結束其余的子線程(守護線程)自動關閉,就免去了還要繼續關閉子線程的麻煩。如:Java垃圾回收線程就是一個典型的守護線程;內存資源或者線程的管理,但是非守護線程也可以。