本篇文章主要介紹了淺談java中守護線程與用戶線程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧
Java線程分成兩類分別為daemon線程(守護線程)和User線程(用戶線程),在JVM啟動時候會呼叫main函數,main函數所在的線程是一個使用者線程,這個是我們可以看到的線程,其實JVM內部同時也啟動了很多守護線程,像是垃圾回收線程。那麼守護線程和使用者線程有什麼差別那?其中一個差異是當最後一個非守護線程結束時候,JVM會正常退出,而不管目前是否有守護線程,也就是說守護線程是否結束並不會影響JVM的退出。言下之意是只要有一個使用者執行緒還沒結束正常情況下JVM就不會退出。
那麼Java中如何建立一個守護線程那?程式碼如下:
public static void main(String[] args) { Thread daemonThread = new Thread(new Runnable() { public void run() { } }); //设置为守护线程 daemonThread.setDaemon(true); daemonThread.start(); }
可知只需要設定執行緒的daemon參數為true。
下面透過範例來加深使用者執行緒與守護執行緒的差異的理解,首先看下面程式碼:
public static void main(String[] args) { Thread thread = new Thread(new Runnable() { public void run() { for(;;){} } }); //启动子线 thread.start(); System.out.print("main thread is over"); }
結果輸出為:
如上程式碼在main線程中創建了一個thread線程,thread線程裡面是無限循環,運行程式碼從結果看main線程已經運行結束了,那麼JVM進行已經退出了?從IDE的輸出結果右邊上的紅色方塊說明JVM程序並沒有退出,另外
mac上執行ps -eaf | grep java會輸出結果,也可以證明這個結論。
這個結果說明了當父執行緒結束後,子執行緒還是可以繼續存在的,也就是子執行緒的生命週期並不受父執行緒的影響。也說明了當用戶執行緒還存在的情況下JVM進程並不會終止。那我們把上面的thread執行緒設定為守護執行緒後在運行看看會有什麼效果:
//设置为守护线程 thread.setDaemon(true); //启动子线 thread.start();
執行結果為:
#如上在啟動線程前設定線程為守護線程,從輸出結果可知JVM程序已經終止了,執行ps -eaf |grep java 也看不到JVM程序了。這個範例裡面main函數是唯一的使用者線程,thread線程是守護線程,當main線程運行結束後,JVM發現目前已經沒有使用者線程了,就會終止JVM程式。
Java中在main執行緒執行結束後,JVM會自動啟動一個叫做DestroyJavaVM線程,該執行緒會等待所有使用者執行緒結束後終止JVM進程,以下透過簡單的JVM程式碼來證明這個結論:
翻開JVM的程式碼,最後會呼叫到JavaMain這個c函數
int JNICALL JavaMain(void * _args) { ... //执行Java中的main函数 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); //main函数返回值 ret = (*env)->ExceptionOccurred(env) == NULL ? 0 : 1; //等待所有非守护线程结束,然后销毁JVM进程 LEAVE(); }
LEAVE是c語言裡面的一個巨集定義,定義如下:
#define LEAVE() \ do { \ if ((*vm)->DetachCurrentThread(vm) != JNI_OK) { \ JLI_ReportErrorMessage(JVM_ERROR2); \ ret = 1; \ } \ if (JNI_TRUE) { \ (*vm)->DestroyJavaVM(vm); \ return ret; \ } \ } while (JNI_FALSE)
上面巨集的作用實際上是創建了一個名字叫做DestroyJavaVM的執行緒來等待所有使用者執行緒結束。
總結:如果你想在主線程結束後JVM進程馬上結束,那麼創建線程的時候可以設定線程為守護線程,否者如果希望主線程結束後子線程繼續工作,等子線程結束後在讓JVM進程結束那麼就設定子線程為用戶線程,開源框架Tomcat中就是用了守護線程和用戶線程聯合運行起來的,具體敬請期待Java並發編程基礎之並發包源碼剖析一書出版。
以上是Java中關於守護線程和使用者線程的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!