java守護執行緒與非守護執行緒的區別
阿新 • • 發佈:2020-07-25
守護執行緒與使用者執行緒
使用者執行緒:我們平常建立的普通執行緒。
守護執行緒:用來服務於使用者執行緒;不需要上層邏輯介入
java執行緒分為守護執行緒和非守護執行緒,當java jvm檢測主執行緒或其他子執行緒執行完之後,守護執行緒也會馬上停止執行,我們可以使用Thread.setDaemon(ture或false)來設定一個執行緒是守護執行緒還是非守護執行緒,預設為false,可以通過Thread.isDaemon()方法查詢該執行緒是否是守護執行緒
1:我們將用案例來告訴你守護執行緒和非守護執行緒的區別和用法,程式碼如下,先設定其為守護執行緒。
public classDeamonThread { 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垃圾回收執行緒就是一個典型的守護執行緒;記憶體資源或者執行緒的管理,但是非守護執行緒也可以。