欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談java中守護線程與用戶線程

 更新時間:2017年09月29日 15:04:19   作者:今天你不奮斗明天你就落后  
本篇文章主要介紹了淺談java中守護線程與用戶線程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

Java線程分為兩類分別為daemon線程(守護線程)和User線程(用戶線程),在JVM啟動時候會調用main函數,main函數所在的線程是一個用戶線程,這個是我們可以看到的線程,其實JVM內部同時還啟動了好多守護線程,比如垃圾回收線程。那么守護線程和用戶線程有什么區(qū)別那?區(qū)別之一是當最后一個非守護線程結束時候,JVM會正常退出,而不管當前是否有守護線程,也就是說守護線程是否結束并不影響JVM的退出。言外之意是只要有一個用戶線程還沒結束正常情況下JVM就不會退出。

那么Java中如何創(chuàng)建一個守護線程那?代碼如下:

public static void main(String[] args) {

    Thread daemonThread = new Thread(new Runnable() {
      public void run() {
        
      }
    });
    
    //設置為守護線程
    daemonThread.setDaemon(true);
    daemonThread.start();
    
  } 

可知只需要設置線程的daemon參數為true即可。

下面通過例子來加深用戶線程與守護線程的區(qū)別的理解,首先看下面代碼:

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線程中創(chuàng)建了一個thread線程,thread線程里面是無限循環(huán),運行代碼從結果看main線程已經運行結束了,那么JVM進行已經退出了?從IDE的輸出結果右側上的紅色方塊說明JVM進程并沒有退出,另外
mac上執(zhí)行ps -eaf | grep java會輸出結果,也可以證明這個結論。

這個結果說明了當父線程結束后,子線程還是可以繼續(xù)存在的,也就是子線程的生命周期并不受父線程的影響。也說明了當用戶線程還存在的情況下JVM進程并不會終止。那么我們把上面的thread線程設置為守護線程后在運行看看會有什么效果:

    //設置為守護線程
    thread.setDaemon(true);
    //啟動子線
    thread.start();

執(zhí)行結果為:

如上在啟動線程前設置線程為守護線程,從輸出結果可知JVM進程已經終止了,執(zhí)行ps -eaf |grep java 也看不到JVM進程了。這個例子里面main函數是唯一的用戶線程,thread線程是守護線程,當main線程運行結束后,JVM發(fā)現當前已經沒有用戶線程了,就會終止JVM進程。

Java中在main線程運行結束后,JVM會自動啟動一個叫做DestroyJavaVM線程,該線程會等待所有用戶線程結束后終止JVM進程,下面通過簡單的JVM代碼來證明這個結論:

翻開JVM的代碼,最終會調用到JavaMain這個c函數

int JNICALL
JavaMain(void * _args)
{  
  ...
  //執(zhí)行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)

上面宏的作用實際是創(chuàng)建了一個名字叫做DestroyJavaVM的線程來等待所有用戶線程結束。

總結:如果你想在主線程結束后JVM進程馬上結束,那么創(chuàng)建線程的時候可以設置線程為守護線程,否者如果希望主線程結束后子線程繼續(xù)工作,等子線程結束后在讓JVM進程結束那么就設置子線程為用戶線程,開源框架Tomcat中就是用了守護線程和用戶線程聯合運行起來的,具體敬請期待Java并發(fā)編程基礎之并發(fā)包源碼剖析一書出版。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • IntelliJ-Idea導出可執(zhí)行Jar流程解析

    IntelliJ-Idea導出可執(zhí)行Jar流程解析

    這篇文章主要介紹了IntelliJ-Idea導出可執(zhí)行Jar流程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • Nacos封裝通用HttpClient詳解

    Nacos封裝通用HttpClient詳解

    這篇文章主要介紹了Nacos封裝通用HttpClient用法,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • java中封裝JDBC工具類的實例分析

    java中封裝JDBC工具類的實例分析

    在本篇內容里小編給各位分享了一篇關于java中封裝JDBC工具類的實例分析,對此有興趣的朋友們可以學習下。
    2021-03-03
  • JVM核心教程之JVM運行與類加載全過程詳解

    JVM核心教程之JVM運行與類加載全過程詳解

    我們都知道一個java程序運行要經過編譯和執(zhí)行,但是這太概括了,中間還有很多步驟,下面這篇文章主要給大家介紹了關于JVM核心教程之JVM運行與類加載全過程的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下。
    2018-04-04
  • 詳解SpringMVC的類型轉換及驗證方法

    詳解SpringMVC的類型轉換及驗證方法

    在本篇文章里面我們給大家詳細分析了SpringMVC的類型轉換及驗證方法的相關知識,對此有需要的朋友們學習下吧。
    2018-10-10
  • java編寫屬于自己的線程池

    java編寫屬于自己的線程池

    這篇文章主要為大家詳細介紹了java編寫屬于自己的線程池,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-03-03
  • java8日期工具類封裝的實戰(zhàn)記錄

    java8日期工具類封裝的實戰(zhàn)記錄

    java time包中的是類是不可變且線程安全的,新的時間及日期API位于java.time中,下面這篇文章主要給大家介紹了關于java8日期工具類封裝的相關資料,需要的朋友可以參考下
    2021-09-09
  • jpa實現多對多的屬性時查詢的兩種方法

    jpa實現多對多的屬性時查詢的兩種方法

    這篇文章主要介紹了jpa實現多對多的屬性時查詢的兩種方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springboot使用Hutool的JschUtil及下載安裝步驟

    springboot使用Hutool的JschUtil及下載安裝步驟

    這篇文章主要為大家介紹了springboot使用Hutool的JschUtil的方法及下載安裝詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • JDBC 實現通用的增刪改查基礎類方法

    JDBC 實現通用的增刪改查基礎類方法

    下面小編就為大家分享一篇JDBC 實現通用的增刪改查基礎類方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01

最新評論