一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 淺談java中守護線程與用戶線程

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

2021-01-13 14:30今天你不奮斗明天你就落 Java教程

本篇文章主要介紹了淺談java中守護線程與用戶線程,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

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

那么Java中如何創建一個守護線程那?代碼如下:

java" id="highlighter_745923">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
public static void main(String[] args) {
 
    Thread daemonThread = new Thread(new Runnable() {
      public void run() {
        
      }
    });
    
    //設置為守護線程
    daemonThread.setDaemon(true);
    daemonThread.start();
    
  }

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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");
  }

結果輸出為:

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

如上代碼在main線程中創建了一個thread線程,thread線程里面是無限循環,運行代碼從結果看main線程已經運行結束了,那么JVM進行已經退出了?從IDE的輸出結果右側上的紅色方塊說明JVM進程并沒有退出,另外
mac上執行ps -eaf | grep java會輸出結果,也可以證明這個結論。

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

?
1
2
3
4
//設置為守護線程
thread.setDaemon(true);
//啟動子線
thread.start();

執行結果為:

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

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

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

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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語言里面的一個宏定義,定義如下:

?
1
2
3
4
5
6
7
8
9
10
11
#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并發編程基礎之并發包源碼剖析一書出版。

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

原文鏈接:http://www.jianshu.com/p/c9e3001cd821?utm_source=tuicool&utm_medium=referral

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 动漫美女胸被狂揉扒开吃奶动态图 | 国产精品全国探花在线观看 | 黄瓜视频黄版 | 久久精品无码人妻无码AV蜜臀 | 超级碰在线视频 | 免费观看二十女人一摸是水 | 91精品国产亚洲爽啪在线影院 | 百合互慰吃奶互揉漫画 | 青草悠悠视频在线观看 | 传说之下羊妈挤羊奶网站 | 国产嫩草视频 | 青青青青青国产免费手机看视频 | 大陆国产精品视频 | 色爱导航| 欧美性videossex丝袜 | 国色天香社区视频免费观看3 | 日本道高清 | 特黄a大片免费视频 | 黑人日白人| 国产亚洲欧美成人久久片 | 久久视频精品3线视频在线观看 | 国产hd老头老太婆 | 黄瓜视频导航 | 五月天狠狠 | 大肥臀风间由美 中文字幕 大东北chinesexxxx露脸 | 校花在公车上被内射好舒服 | 欧美一区不卡二区不卡三区 | 国产99久久精品 | 大jjjj免费看视频 | 人人做人人爽人人爱 | 九色PORNY真实丨国产大胸 | 久久精品熟女亚洲AV国产 | 亚洲剧情在线 | 调教处男 | 99久久久无码国产精品 | 日韩在线一区二区三区 | 色综合色综合 | 奇米狠狠色 | 2020国产精品亚洲综合网 | 国产v在线在线观看羞羞答答 | 修修视频在线观看 |