精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Thread的Join方法原理

開(kāi)發(fā) 前端
眾所周知,「Java的鎖其實(shí)本質(zhì)上是對(duì)象鎖」,因?yàn)槲覀兦懊嬲{(diào)用的是thread.join(),所以這里的“鎖”對(duì)象其實(shí)thread這個(gè)對(duì)象。那這里wait釋放的是thread這個(gè)對(duì)象鎖。

[[410940]]

本文轉(zhuǎn)載自微信公眾號(hào)「編了個(gè)程」,作者Yasin x 。轉(zhuǎn)載本文請(qǐng)聯(lián)系編了個(gè)程公眾號(hào)。

Y說(shuō)

今天沒(méi)什么要說(shuō)的。我個(gè)人很喜歡拍天空的照片,放一張前段時(shí)間晚上拍的照片吧。

join方法釋放鎖嗎?

前段時(shí)間,有一個(gè)讀者私信我,問(wèn)了這么一個(gè)問(wèn)題:Thread實(shí)例的join方法內(nèi)部是調(diào)用的wait方法,而wait方法是會(huì)釋放鎖的,為什么網(wǎng)上很多文章(包括我們之前寫(xiě)的開(kāi)源書(shū)《深入淺出Java多線程》)會(huì)說(shuō)join方法不釋放鎖?

釋放thread對(duì)象鎖

我們先用書(shū)中的一個(gè)例子說(shuō)起:

  1. public class Join { 
  2.     static class ThreadA implements Runnable { 
  3.  
  4.         @Override 
  5.         public void run() { 
  6.             try { 
  7.                 System.out.println("我是子線程,我先睡一秒"); 
  8.                 Thread.sleep(1000); 
  9.                 System.out.println("我是子線程,我睡完了一秒"); 
  10.             } catch (InterruptedException e) { 
  11.                 e.printStackTrace(); 
  12.             } 
  13.         } 
  14.     } 
  15.  
  16.     public static void main(String[] args) throws InterruptedException { 
  17.         Thread thread = new Thread(new ThreadA()); 
  18.         thread.start(); 
  19.         thread.join(); 
  20.         System.out.println("如果不加join方法,我會(huì)先被打出來(lái),加了就不一樣了"); 
  21.     } 

在這個(gè)例子中,我們?cè)趍ain方法中調(diào)用了thread.join(),打印出來(lái)的效果就是:

  1. 我是子線程,我先睡一秒 
  2. 我是子線程,我睡完了一秒 
  3. 如果不加join方法,我會(huì)先被打出來(lái),加了就不一樣了 

這個(gè)例子想要表達(dá)的意圖很簡(jiǎn)單,就是通過(guò)thread實(shí)例的join方法,達(dá)到main線程等待thread線程執(zhí)行完后再繼續(xù)執(zhí)行的效果。

那join方法底層是如何實(shí)現(xiàn)這個(gè)功能的呢?究竟會(huì)不會(huì)釋放鎖呢?我們點(diǎn)進(jìn)去看看源碼。

  1. if (millis == 0) { 
  2.     while (isAlive()) { 
  3.         wait(0); 
  4.     } 
  5. else { 
  6.     while (isAlive()) { 
  7.         long delay = millis - now; 
  8.         if (delay <= 0) { 
  9.             break; 
  10.         } 
  11.         wait(delay); 
  12.         now = System.currentTimeMillis() - base; 
  13.     } 

可以看到,join的底層是調(diào)用的wait(long)方法。而wait方法是Object類(lèi)型的實(shí)例方法,會(huì)釋放當(dāng)前Object的鎖,且需要拿到當(dāng)前Object的鎖才行。

這么說(shuō)可能有點(diǎn)繞。眾所周知,「Java的鎖其實(shí)本質(zhì)上是對(duì)象鎖」,因?yàn)槲覀兦懊嬲{(diào)用的是thread.join(),所以這里的“鎖”對(duì)象其實(shí)thread這個(gè)對(duì)象。那這里wait釋放的是thread這個(gè)對(duì)象鎖。

我們把上面的main方法簡(jiǎn)單改一下,用另一個(gè)線程是占住thread這個(gè)對(duì)象鎖,就比較直觀了:

  1. public static void main(String[] args) throws InterruptedException { 
  2.     Thread thread = new Thread(new ThreadA()); 
  3.     thread.start(); 
  4.     new Thread(() -> { 
  5.         // 把thread對(duì)象作為鎖占住,這樣下面的join里面的wait只有等鎖釋放了才能執(zhí)行。 
  6.         synchronized (thread) { 
  7.             try { 
  8.                 System.out.println("我占住了thread鎖"); 
  9.                 Thread.sleep(10000); 
  10.                 System.out.println("我thread鎖釋放了"); 
  11.             } catch (InterruptedException e) { 
  12.                 e.printStackTrace(); 
  13.             } 
  14.         } 
  15.     }).start(); 
  16.     thread.join(); 
  17.     System.out.println("如果不加join方法,我會(huì)先被打出來(lái),加了就不一樣了"); 

打印結(jié)果:

  1. 我是子線程,我先睡一秒 
  2. 我占住了thread鎖 
  3. 我是子線程,我睡完了一秒 
  4. 我thread鎖釋放了 
  5. 如果不加join方法,我會(huì)先被打出來(lái),加了就不一樣了 

這就印證了那句話:wait方法執(zhí)行前,是需要獲取當(dāng)前對(duì)象的鎖的。

所以回歸到最開(kāi)始的問(wèn)題:join()方法會(huì)釋放鎖嗎?嚴(yán)瑾的答案是它會(huì)釋放thread實(shí)例的對(duì)象鎖,但不會(huì)釋放其它對(duì)象鎖(包括main線程)。stackoverflow也對(duì)這個(gè)有討論:Does Thread.join() release the lock? Or continue to hold it?。

簡(jiǎn)單來(lái)說(shuō),你說(shuō)它釋放了鎖也對(duì),因?yàn)樗_實(shí)通過(guò)wait方法釋放了thread對(duì)象鎖,你說(shuō)它沒(méi)釋放鎖也對(duì),因?yàn)閺恼{(diào)用線程的角度來(lái)看,它并沒(méi)有釋放當(dāng)前調(diào)用線程持有的對(duì)象鎖。

當(dāng)然,為了防止其它讀者看到這也有這個(gè)疑惑,我直接把文中的這句話刪掉了。

^image.png^

誰(shuí)喚醒了?

源碼看到這,我又有了一個(gè)新的疑問(wèn):join方法內(nèi)部是一個(gè)while循環(huán)。wait釋放了鎖,那必然會(huì)有一個(gè)人來(lái)喚醒它,程序才能夠繼續(xù)往下走。那必然有一個(gè)地方調(diào)用了thread對(duì)象的notify方法。

我們?cè)赥hread類(lèi)里面可以找到一個(gè)exit()方法,上面?zhèn)渥?xiě)著:This method is called by the system to give a Thread a chance to clean up before it actually exits.

這么簡(jiǎn)單的英文大家應(yīng)該都能看懂吧?

里面有這么一段代碼:

  1. if (group != null) { 
  2.     group.threadTerminated(this); 
  3.     group = null
  4.  
  5. void threadTerminated(Thread t) { 
  6.     synchronized (this) { 
  7.         remove(t); 
  8.  
  9.         if (nthreads == 0) { 
  10.             notifyAll(); 
  11.         } 
  12.         if (daemon && (nthreads == 0) && 
  13.             (nUnstartedThreads == 0) && (ngroups == 0)) 
  14.         { 
  15.             destroy(); 
  16.         } 
  17.     } 

一開(kāi)始我以為是在這里喚醒的,但仔細(xì)一看,這里調(diào)用的對(duì)象是ThreadGroup的實(shí)例,而不是thread實(shí)例。所以應(yīng)該不是這個(gè)地方。

經(jīng)過(guò)一通google之后,我又在stackoverflow上找到了正確的答案(stackoverflow, yyds):who and when notify the thread.wait() when thread.join() is called?

答案顯示,這是在JVM層面去做的事:

  1. static void ensure_join(JavaThread* thread) { 
  2.   // We do not need to grap the Threads_lock, since we are operating on ourself. 
  3.   Handle threadObj(thread, thread->threadObj()); 
  4.   assert(threadObj.not_null(), "java thread object must exist"); 
  5.   ObjectLocker lock(threadObj, thread); 
  6.   // Ignore pending exception (ThreadDeath), since we are exiting anyway 
  7.   thread->clear_pending_exception(); 
  8.   // Thread is exiting. So set thread_status field in  java.lang.Thread class to TERMINATED. 
  9.   java_lang_Thread::set_thread_status(threadObj(), java_lang_Thread::TERMINATED); 
  10.   // Clear the native thread instance - this makes isAlive return false and allows the join() 
  11.   // to complete once we've done the notify_all below 
  12.   java_lang_Thread::set_thread(threadObj(), NULL); 
  13.   lock.notify_all(thread); 
  14.   // Ignore pending exception (ThreadDeath), since we are exiting anyway 
  15.   thread->clear_pending_exception(); 

可以看到除了notify_all以外,它其實(shí)做了很多掃尾的工作。包括處理異常、設(shè)置線程狀態(tài)等。

如果線程沒(méi)啟動(dòng)

再把代碼改一下,如果線程沒(méi)有通過(guò)start啟動(dòng)會(huì)怎樣呢?

  1. Thread thread = new Thread(new ThreadA()); 
  2. // thread.start(); 
  3. thread.join(); 
  4. System.out.println("如果不加join方法,我會(huì)先被打出來(lái),加了就不一樣了"); 

會(huì)直接執(zhí)行最后一行代碼打印出來(lái)。

看join源碼就知道了,在wait之前,會(huì)有一個(gè)isAlive()的判斷,看當(dāng)前線程是否是alive的。如果沒(méi)有start,那就會(huì)直接返回false,不進(jìn)入wait。

總結(jié)

join方法會(huì)釋放thread對(duì)象鎖,底層是wait方法,在JVM層面通過(guò)notify_all來(lái)喚醒的。

 

責(zé)任編輯:武曉燕 來(lái)源: 編了個(gè)程
相關(guān)推薦

2023-05-08 00:08:51

Hive機(jī)制場(chǎng)景

2024-05-28 00:00:02

Java線程程序

2009-04-02 10:23:13

實(shí)現(xiàn)JoinMySQL

2017-08-31 16:17:35

SQL優(yōu)化器原理

2009-06-29 18:08:51

Java多線程join方法

2018-01-25 19:09:40

JavaThreadLocal線程

2009-05-07 15:02:42

OracleJoin查詢

2009-08-26 16:58:12

調(diào)用C# Thread

2023-06-07 07:43:57

數(shù)據(jù)庫(kù)JOIN類(lèi)型

2023-07-03 08:10:51

2010-05-21 17:30:28

2021-09-10 06:50:03

HashMapHash方法

2011-06-22 15:42:18

QT 信號(hào)

2016-12-21 14:35:46

響應(yīng)式網(wǎng)頁(yè)布局實(shí)現(xiàn)方法原理

2013-03-11 10:07:36

主干交換機(jī)交換機(jī)工作原理交換機(jī)設(shè)備

2023-08-08 00:06:31

2021-10-15 11:37:44

反爬蟲(chóng)破解

2022-03-30 08:54:21

線程 Thread判斷線程池任務(wù)Java

2025-08-13 06:00:00

Flink SQLFlink大數(shù)據(jù)

2012-02-01 14:28:03

Java線程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

久久精品青青大伊人av| 在线视频成人| 在线精品在线| 亚洲最大在线视频| 天天爽夜夜爽视频| 久草免费在线视频| 国产精品乱码一区二三区小蝌蚪| 成人在线视频网站| 久久久久久久极品| 欧美日韩国产传媒| 精品国产乱码久久久久久免费| 国产91对白刺激露脸在线观看| 婷婷激情在线| 国产一区啦啦啦在线观看| 久久久免费在线观看| 婷婷色一区二区三区| 成人av资源网址| 欧美性猛交xxxx黑人交| 麻豆tv在线播放| 日本高清视频在线观看| 91原创在线视频| 92国产精品久久久久首页| 国产成人一级片| 国产精品a级| 日韩在线免费观看视频| 欧美无人区码suv| 国产一区二区三区| 欧美午夜不卡视频| 无码人妻精品一区二区三区在线| а√天堂资源地址在线下载| 国产三级三级三级精品8ⅰ区| 粉嫩av四季av绯色av第一区| 岳乳丰满一区二区三区| 香蕉精品999视频一区二区| 欧美国产欧美亚洲国产日韩mv天天看完整 | 狠狠干狠狠久久| 日韩免费在线观看av| 日本www在线观看| 激情亚洲网站| 黄色成人在线播放| 天堂av免费看| 91caoporn在线| 久久久国产综合精品女国产盗摄| 激情欧美国产欧美| 日韩毛片中文字幕| 911亚洲精选| 亚洲一区二区三区免费| 91精品福利在线一区二区三区 | 澳门成人av网| 精品成人久久av| 欧洲精品一区二区三区久久| 亚洲第一图区| 一区二区免费在线播放| 欧美美女黄色网| 性欧美猛交videos| 亚洲最大色网站| 精品丰满人妻无套内射| 超碰在线视屏| 欧美日韩国产一区中文午夜| 国产成人无码a区在线观看视频| av资源一区| 精品久久久一区二区| 欧美s码亚洲码精品m码| 成人国产二区| 欧美在线观看一二区| 男女男精品视频站| 日韩国产一二三区| 日韩视频一区在线观看| 香蕉久久久久久av成人| 岛国成人av| 亚洲女人被黑人巨大进入al| 免费福利视频网站| 国产精品久久久久9999赢消| 久久综合国产精品台湾中文娱乐网| 青青草自拍偷拍| 午夜激情一区| 97超级碰碰碰久久久| 中文字幕手机在线视频| 精品一区二区三区在线播放| 91视频免费进入| 四虎影视在线观看2413| 欧美国产一区二区| 国产一级大片免费看| 美女露胸视频在线观看| 香蕉加勒比综合久久 | 天天干天天干天天| 日韩在线影视| 国产一区二区三区四区福利| 欧美日韩午夜视频| 国产日韩欧美| 91久久精品在线| 午夜视频福利在线观看| 国产精品久久久久精k8| 欧美视频免费看欧美视频| 99久久精品一区二区成人| 日韩一区二区免费高清| 国产黄色网址在线观看| 亚洲成人日韩| 国产99在线|中文| 精品国产无码AV| 久久精品视频免费| 一区二区精品在线| 深夜在线视频| 欧美一级二级在线观看| 国产高潮呻吟久久| 欧美午夜影院| 国产免费成人av| 无码国产色欲xxxx视频| 自拍偷拍亚洲欧美日韩| 黄色影院一级片| 视频一区在线| 中文字幕亚洲无线码在线一区| 久久精品久久精品久久| 麻豆成人av在线| 秋霞毛片久久久久久久久| 日本小视频在线免费观看| 精品视频一区二区三区免费| 噜噜噜在线视频| 欧美视频网站| 国产乱对白刺激视频不卡| 久久久免费观看视频| 一本一道精品欧美中文字幕| 91免费国产视频网站| 日韩一级片一区二区| 欧美日韩卡一| 亚洲视频第一页| 日韩精品视频免费看| 国产一区二区精品久久99| 日韩欧美电影一区二区| 欧美男人天堂| 亚洲第一精品自拍| 久草免费新视频| 国产精品中文字幕日韩精品| 亚洲人成77777| 欧美日韩视频免费观看| 欧美日韩国产在线播放网站| 蜜臀久久99精品久久久久久| 国产农村妇女精品一二区| 国产精品一区二区三区不卡| 在线观看午夜av| 8v天堂国产在线一区二区| 国产18无套直看片| 久久亚洲综合| 欧美一区二区三区精美影视| 韩日精品一区二区| 国产丝袜一区二区| 欧美a∨亚洲欧美亚洲| 免费在线性爱视频| 麻豆一区二区三| 午夜视频久久久| 成人精品国产| 综合欧美国产视频二区| 在线观看毛片视频| 国产精品国模大尺度视频| 蜜臀av免费观看| 日本不卡高清| 91精品视频在线免费观看| 超碰个人在线| 欧美成人猛片aaaaaaa| 久久精品国产亚洲AV无码男同 | 日韩欧美aaa| 91视频免费观看网站| 日韩不卡在线观看日韩不卡视频| 日韩片电影在线免费观看| 欧美日韩精品一区二区三区视频| 在线日韩欧美视频| 91福利免费视频| 亚洲黄色在线视频| 色综合久久五月| 日本午夜精品一区二区三区电影 | 国语精品一区| 国产在线观看一区| 182在线播放| 亚洲区免费影片| 国产精品视频一区二区三区,| 一区二区在线看| 一级特级黄色片| 美女www一区二区| 久久福利一区二区| 亚洲精品小区久久久久久| 国产精品十八以下禁看| 宅男网站在线免费观看| 亚洲乱码av中文一区二区| 亚洲精品一区二区二区| 日本中文字幕在线2020| 欧美午夜精品久久久久久人妖| aaaaa级少妇高潮大片免费看| 另类小说欧美激情| 天堂8在线天堂资源bt| 自拍视频一区| 亚洲一区二区三区在线免费观看 | 99精品视频在线| av在线不卡一区| 欧美成人精品一区二区男人小说| 久久好看免费视频| 婷婷伊人综合中文字幕| 欧美日韩国产123区| 日本少妇裸体做爰| 国产精品久久久一区麻豆最新章节| 男人添女人荫蒂国产| 久久久综合网| av在线免费观看国产| 欧美中文一区二区| 精品一卡二卡三卡四卡日本乱码 | 3atv一区二区三区| 亚洲免费在线观看av| 亚洲色图视频免费播放| 免费黄色在线视频| 高清国产一区二区三区| 国产原创精品在线| 亚洲在线国产日韩欧美| 日本久久久网站| 成人影院在线| 欧美成ee人免费视频| caoporn成人| 成人免费在线视频网址| 亚洲一区二区三区四区| 97精品国产97久久久久久春色| аⅴ资源新版在线天堂| 日韩毛片中文字幕| 内射后入在线观看一区| 91麻豆精品国产自产在线观看一区 | 久久久久久久久久久久国产精品| 久久综合综合久久综合| 欧在线一二三四区| 国产欧美一区二区三区国产幕精品| 欧洲xxxxx| 91亚洲人成网污www| 日韩免费电影一区二区| 亚洲小说图片视频| 九色91视频| 国产福利资源一区| 国产98在线|日韩| 精品国产乱码一区二区三区| 国产免费一区二区三区在线观看| 欧美日韩免费观看视频| 国产成人激情小视频| 成人免费无遮挡| 欧亚精品中文字幕| 欧美巨大丰满猛性社交| 69av成年福利视频| sm性调教片在线观看| 97视频在线观看成人| 97蜜桃久久| 8050国产精品久久久久久| 免费观看日批视频| 国产欧美一区| 99re视频在线| 亚洲三区欧美一区国产二区| 91夜夜揉人人捏人人添红杏| 亚洲精品成a人ⅴ香蕉片| 国产中文字幕日韩| 成人国产精品一区二区网站| 95av在线视频| 国产精品一区二区美女视频免费看| 成人高h视频在线| 日韩欧美专区| 99久久99久久精品国产片| 日韩精品中文字幕一区二区| 国产精品大全| 欧美a大片欧美片| 欧美黄色直播| 日韩精品水蜜桃| 国产免费一区二区三区四在线播放| 9191国语精品高清在线| 可以在线看黄的网站| 好吊日精品视频| 男人添女人下面高潮视频| 久久福利一区| 国内外成人免费在线视频| 国内久久婷婷综合| 秘密基地免费观看完整版中文| 波多野结衣91| 日韩一级av毛片| 自拍偷拍亚洲综合| 欧美不卡视频在线观看| 欧美亚洲禁片免费| 国产手机av在线| 亚洲国产精品女人久久久| 黄色片在线播放| 久久亚洲精品毛片| а√在线天堂官网| 国产91热爆ts人妖在线| 欧美伊人亚洲伊人色综合动图| 97视频中文字幕| 国产精品一区二区三区av麻| 手机成人av在线| 在线欧美日韩| 中文字幕av专区| 国产一区免费看| 亚洲国产一区二区三区| 欧美日韩一级黄色片| 欧美日韩aaa| 天天干,夜夜操| 日韩亚洲成人av在线| 99热99re6国产在线播放| 国产精品91久久久| 成人激情自拍| 亚洲精品国产精品久久| 亚洲人成久久| 三日本三级少妇三级99| 久久久青草青青国产亚洲免观| 亚洲图片第一页| 婷婷开心激情综合| 国产女人高潮的av毛片| 亚洲男人第一网站| 任你弄在线视频免费观看| 国产精品久久久91| 麻豆精品少妇| 欧美一级黄色录像片| 视频一区在线播放| 久久久久亚洲AV成人网人人小说| 国产精品人人做人人爽人人添| 日韩精品在线免费看| 91精品国产综合久久福利软件| 欧美色图另类| 97色在线视频观看| 欧美成年网站| 在线播放豆国产99亚洲| 美女被久久久| 日本japanese极品少妇| 亚洲一线二线三线视频| 国产精品国产av| 亚洲乱码国产乱码精品精天堂| 天天干在线视频论坛| 成人福利在线视频| 欧美呦呦网站| www欧美激情| 久久久久国色av免费看影院| av大片免费观看| 精品国产免费人成电影在线观看四季 | 老牛精品亚洲成av人片| 日韩精品亚洲视频| 成年网站在线视频网站| 91日韩久久| 欧美特黄一区| 国产伦理在线观看| 亚洲欧美日韩久久| 国产一区二区三区四区视频 | 国产成人精品日本亚洲11| 四季av一区二区三区免费观看| 91av俱乐部| 国产亚洲一区二区三区在线观看| 草久久免费视频| 日韩国产一区三区| 成人勉费视频| 日韩av一区二区三区在线| 久久久久久婷| 人成免费在线视频| 欧美日韩久久久久久| 视频一区二区三区不卡| 国产区亚洲区欧美区| 婷婷综合五月| 无套内谢丰满少妇中文字幕| 亚洲免费av观看| 亚洲av无码乱码在线观看性色| 精品自拍视频在线观看| 91久久偷偷做嫩草影院电| 久久成人福利视频| 91在线小视频| 神马久久久久久久| 综合网中文字幕| 白嫩亚洲一区二区三区| 黄色片免费在线观看视频| 成人在线一区二区三区| 亚洲日本韩国在线| 亚洲区中文字幕| 国产精品久久久久77777丨| 国产精品av免费| 岛国精品在线观看| www.com国产| 最近2019中文字幕第三页视频 | 久久99亚洲网美利坚合众国| av一区二区三区免费| 狠狠88综合久久久久综合网| 亚洲国产精品无码久久久久高潮 | 色棕色天天综合网| 免费看涩涩视频| 亚洲精品中文字幕乱码三区 | 伊人久久大香| 久久成人福利视频| 国产欧美日韩激情| 99热这里只有精品99| 26uuu亚洲伊人春色| 经典一区二区| 日本少妇xxx| 欧美性猛交xxxx乱大交| 福利在线视频导航| 成人av电影免费| 久久精品一区二区三区中文字幕 | 你懂得在线网址| 亚洲在线一区二区| 性色av一区二区怡红| 裸体武打性艳史| 亚洲欧洲高清在线| 网站一区二区| 亚洲少妇第一页| 亚洲国产视频网站| 日本www在线观看| 久久久99国产精品免费|