線程分類:java
User Thread(用戶線程)spa
Daemon Thread(守護線程) .net
定義:線程
守護線程--也稱「服務線程」,在沒有用戶線程可服務時會自動離開。
優先級:code
守護線程的優先級比較低,用於爲系統中的其它對象和線程提供服務。
設置: 對象
經過setDaemon(true)來設置線程爲「守護線程」;將一個用戶線程設置爲守護線程的方式是在 線程對象建立 以前 用線程對象的setDaemon方法。example: 垃圾回收線程就是一個經典的守護線程,當咱們的程序中再也不有任何運行的Thread,程序就不會再產生垃圾,垃圾回收器也就無事可作,因此當垃圾回收線程是JVM上僅剩的線程時,垃圾回收線程會自動離開。它始終在低級別的狀態中運行,用於實時監控和管理系統中的可回收資源。blog
生命週期: 生命週期
守護進程(Daemon)是運行在後臺的一種特殊進程。它獨立於控制終端而且週期性地執行某種任務或等待處理某些發生的事件。也就是說守護線程不依賴於終端,可是依賴於系統,與系統「同生共死」。那Java的守護線程是什麼樣子的呢。當JVM中全部的線程都是守護線程的時候,JVM就能夠退出了;若是還有一個或以上的非守護線程則JVM不會退出。進程
用個比較通俗的好比,任何一個守護線程都是整個JVM中全部非守護線程的保姆: 只要當前JVM實例中尚存在任何一個非守護線程沒有結束,守護線程就所有工做;只有當最後一個非守護線程結束時,守護線程隨着JVM一同結束工做。Daemon的做用是爲其餘線程的運行提供便利服務,守護線程最典型的應用就是 GC (垃圾回收器),它就是一個很稱職的守護者。User和Daemon二者幾乎沒有區別,惟一的不一樣之處就在於虛擬機的離開:若是 User Thread已經所有退出運行了,只剩下Daemon Thread存在了,虛擬機也就退出了。 由於沒有了被守護者,Daemon也就沒有工做可作了也就沒有繼續運行程序的必要了。值得一提的是,守護線程並不是只有虛擬機內部提供,用戶在編寫程序時也能夠本身設置守護線程。下面的方法就是用來設置守護線程的。事件
Thread daemonTread = new Thread(); // 設定 daemonThread 爲 守護線程,default false(非守護線程) daemonThread.setDaemon(true); // 驗證當前線程是否爲守護線程,返回 true 則爲守護線程 daemonThread.isDaemon();
守護線程須要注意點:
(1) thread.setDaemon(true)必須在thread.start()以前設置,不然會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置爲守護線程。
(2) 在Daemon線程中產生的新線程也是Daemon的。
(3) 不要認爲全部的應用均可以分配給Daemon來進行服務,好比讀寫操做或者計算邏輯。 (不能保證,當用戶進程都退出了,守護進程的 讀寫任務是否完成,即便沒有完成,守護進程也會自動退出)
守護進程進行讀寫文件操做的例子:
//完成文件輸出的守護線程任務 import java.io.*; class TestRunnable implements Runnable{ public void run(){ try{ Thread.sleep(1000);//守護線程阻塞1秒後運行 File f=new File("daemon.txt"); FileOutputStream os=new FileOutputStream(f,true); os.write("daemon".getBytes()); } catch(IOException e1){ e1.printStackTrace(); } catch(InterruptedException e2){ e2.printStackTrace(); } } } public class TestDemo2{ public static void main(String[] args) throws InterruptedException { Runnable tr=new TestRunnable(); Thread thread=new Thread(tr); thread.setDaemon(true); //設置守護線程 thread.start(); //開始執行分進程 } } //運行結果:文件daemon.txt中沒有"daemon"字符串。
緣由也很簡單,直到主線程完成,守護線程仍處於1秒的阻塞狀態。這個時候主線程很快就運行完了,虛擬機退出,Daemon中止服務,輸出操做天然失敗了。
守護進程和用戶進程同時執行任務的例子:
public class Test { public static void main(String args) { Thread t1 = new MyCommon(); Thread t2 = new Thread(new MyDaemon()); t2.setDaemon(true); //設置爲守護線程 t2.start(); t1.start(); } } class MyCommon extends Thread { public void run() { for (int i = 0; i < 5; i++) { System.out.println("線程1第" + i + "次執行!"); try { Thread.sleep(7); } catch (InterruptedException e) { e.printStackTrace(); } } } } class MyDaemon implements Runnable { public void run() { for (long i = 0; i < 9999999L; i++) { System.out.println("後臺線程第" + i + "次執行!"); try { Thread.sleep(7); } catch (InterruptedException e) { e.printStackTrace(); } } } }
執行的結果爲:
後臺線程第0次執行!
線程1第0次執行!
線程1第1次執行!
後臺線程第1次執行!
後臺線程第2次執行!
線程1第2次執行!
線程1第3次執行!
後臺線程第3次執行!
線程1第4次執行!
後臺線程第4次執行!
後臺線程第5次執行!
後臺線程第6次執行!
後臺線程第7次執行!
Process finished with exit code 0
當用戶線程運行結束後,守護線程任務並無結束就退出了。
轉載自:
http://blog.csdn.net/shimiso/article/details/8964414