java的守護線程與非守護線程

最近從新研究Java基礎知識,發現之前太多知識知識略略帶過了,比較說Java的線程機制,在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程) ,(PS:之前忽略了)。java

       估計學過Unix開發可是沒有細緻學習Java的同窗們會疑惑了,操做系統裏面是沒有所謂的守護線程的概念,只有守護進程一說,可是Java語言機制是構建在JVM的基礎之上的,意思是Java平臺把操做系統的底層給屏蔽起來,因此它能夠在它本身的虛擬的平臺裏面構造出對本身有利的機制,而語言或者說平臺的設計者多多少少是收到Unix思想的影響,而守護線程機制又是對JVM這樣的平臺湊合,因而守護線程應運而生。web

       Daemon的做用是爲其餘線程的運行提供服務,好比說GC線程。其實User Thread線程和Daemon Thread守護線程本質上來講去沒啥區別的,惟一的區別之處就在虛擬機的離開:若是User Thread所有撤離,那麼Daemon Thread也就沒啥線程好服務的了,因此虛擬機也就退出了。服務器

       守護線程並不是虛擬機內部能夠提供,用戶也能夠自行的設定守護線程,方法:public final void setDaemon(boolean on) ;可是有幾點須要注意:併發

1)、thread.setDaemon(true)必須在thread.start()以前設置,不然會跑出一個IllegalThreadStateException異常。你不能把正在運行的常規線程設置爲守護線程。  (備註:這點與守護進程有着明顯的區別,守護進程是建立後,讓進程擺脫原會話的控制+讓進程擺脫原進程組的控制+讓進程擺脫原控制終端的控制;因此說寄託於虛擬機的語言機制跟系統級語言有着本質上面的區別)學習

2)、 在Daemon線程中產生的新線程也是Daemon的。  (這一點又是有着本質的區別了:守護進程fork()出來的子進程再也不是守護進程,儘管它把父進程的進程相關信息複製過去了,可是子進程的進程的父進程不是init進程,所謂的守護進程本質上說就是「父進程掛掉,init收養,而後文件0,1,2都是/dev/null,當前目錄到/」)spa

3)、不是全部的應用均可以分配給Daemon線程來進行服務,好比讀寫操做或者計算邏輯。由於在Daemon Thread還沒來的及進行操做時,虛擬機可能已經退出了。操作系統

例子:線程

//完成文件輸出的守護線程任務設計

 1 import java.io.*;  
 2 
 3  
 4 
 5 class TestRunnable implements Runnable{  
 6 
 7     public void run(){  
 8 
 9                try{  
10 
11                   Thread.sleep(1000);//守護線程阻塞1秒後運行  
12 
13                   File f=new File("daemon.txt");  
14 
15                   FileOutputStream os=new FileOutputStream(f,true);  
16 
17                   os.write("daemon".getBytes());  
18 
19            }  
20 
21                catch(IOException e1){  
22 
23           e1.printStackTrace();  
24 
25                }  
26 
27                catch(InterruptedException e2){  
28 
29                   e2.printStackTrace();  
30 
31            }  
32 
33     }  
34 
35 }  
36 
37 public class TestDemo2{  
38 
39     public static void main(String[] args) throws InterruptedException  
40 
41     {  
42 
43         Runnable tr=new TestRunnable();  
44 
45         Thread thread=new Thread(tr);  
46 
47                 thread.setDaemon(true); //設置守護線程  
48 
49         thread.start(); //開始執行分進程  
50 
51     }  
52 
53 }  

 

運行結果:文件daemon.txt中沒有"daemon"字符串。code

可是若是把thread.setDaemon(true); //設置守護線程註釋掉,文件daemon.txt是能夠被寫入daemon字符串的

 

  JRE判斷程序是否執行結束的標準是全部的前臺執線程行完畢了,而無論後臺線程的狀態,所以,在使用後臺線程候必定要注意這個問題。 

可是daemon Thread實際應用在那裏呢?舉個例子,web服務器中的Servlet,容器啓動時後臺初始化一個服務線程,即調度線程,負責處理http請求,而後每一個請求過來調度線程從線程池中取出一個工做者線程來處理該請求,從而實現併發控制的目的。

網上摘的一個圖,方便你們理解:

 

相關文章
相關標籤/搜索