精品欧美一区二区三区在线观看 _久久久久国色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)

国产精品久久精品日日| 日韩激情在线观看| 亚洲精品一区二区三区精华液| 激情五月婷婷六月| 午夜激情在线视频| 免费日本视频一区| 欧美激情乱人伦| 舐め犯し波多野结衣在线观看| 黑人一区二区三区| 亚洲一区二区三区视频在线播放| 久久久久资源| 国产免费无遮挡| 国产精品三上| 欧美成人午夜激情在线| 色婷婷av777| 深夜激情久久| 欧美三级视频在线播放| 精品国偷自产一区二区三区| 成人免费一区二区三区视频网站| 国产一区二区不卡在线| 琪琪第一精品导航| 青娱乐国产盛宴| 色婷婷色综合| 亚洲美女精品成人在线视频| 图片区偷拍区小说区| 成人精品动漫| 欧美日韩国产精品专区| 久久综合亚洲精品| 国产原创视频在线观看| 国产欧美一区二区在线| 国产精品一区在线播放| 国产日韩精品suv| 视频一区视频二区中文| 91成人在线播放| 免费在线看黄网址| 亚洲精品二区三区| 日韩在线中文视频| 欧美xxxx精品| 日韩三级在线| 中文字幕一区电影| 中文字幕伦理片| 国产一区二区三区探花| 亚洲男人天堂手机在线| 少妇饥渴放荡91麻豆| 噜噜噜天天躁狠狠躁夜夜精品 | 成人午夜视频在线播放| 极品少妇一区二区三区| 欧美激情一区二区久久久| 手机在线免费看毛片| 999久久久免费精品国产| 在线播放国产一区二区三区| 69视频在线观看免费| 国产一区二区三区四区五区传媒| 亚洲人成网站免费播放| 中文字幕免费视频| 精品高清在线| 这里只有精品视频| 国产在视频线精品视频| 欧美激情另类| 成人444kkkk在线观看| 成人涩涩小片视频日本| 一精品久久久| 欧美精品video| 日本熟女一区二区| 性色一区二区三区| 国产精品久久久久久久久免费 | 日韩欧美成人一区二区| 亚洲少妇一区二区| 老司机成人在线| 亚洲毛片在线观看.| 国产破处视频在线观看| 久久久久久久久久久9不雅视频| 欧美插天视频在线播放| 日本在线观看中文字幕| 久久精品中文| 国产噜噜噜噜久久久久久久久| 97精品人妻一区二区三区| 国产在线精品一区二区夜色| www.一区二区三区| 日本午夜在线视频| 欧美国产日产图区| 久久天天东北熟女毛茸茸| 国产后进白嫩翘臀在线观看视频| 精品人伦一区二区三区蜜桃免费 | 国产精品7777777| 久久亚洲影院| 成人免费高清完整版在线观看| 亚洲第一成年人网站| 91麻豆swag| 一区二区日本伦理| brazzers在线观看| 欧美午夜激情视频| 国产一伦一伦一伦| 精品欧美午夜寂寞影院| 一区二区三区视频免费| 久草免费在线视频观看| 性欧美videos另类喷潮| 91成人理论电影| 毛片网站在线| 一区二区三区美女| 中文字幕无码不卡免费视频| 91嫩草国产线观看亚洲一区二区 | 欧美性做爰猛烈叫床潮| 国产精品日日摸夜夜爽| 第一sis亚洲原创| 午夜精品一区二区三区视频免费看 | 五月婷婷在线观看| 欧美日韩另类在线| 国产探花在线观看视频| 国产麻豆一区二区三区精品视频| 欧美成人精品一区二区三区| 无码人妻精品一区二区| 成人性色生活片免费看爆迷你毛片| 日韩av在线电影观看| 黄网av在线| 9191成人精品久久| 国产人妻大战黑人20p| 国产一区日韩一区| 国产欧美va欧美va香蕉在线| 先锋av资源站| 一区二区三区精密机械公司| 美女少妇一区二区| 四虎影视精品| 久久久女女女女999久久| 91国内精品久久久| 国产欧美日本一区视频| 欧美日韩二三区| 一区二区三区四区视频免费观看| 中文日韩在线观看| 中日韩黄色大片| 成人亚洲精品久久久久软件| 日本成人在线不卡| 精品亚洲二区| 久久精品国产综合| 一级二级三级视频| 国产精品污网站| 性生交免费视频| 国产一区二区三区四区大秀| 日韩美女av在线免费观看| 天天av综合网| 精品久久久久久久久国产字幕| 欧美午夜精品一区二区| 欧美日韩日本国产亚洲在线| 97久久天天综合色天天综合色hd | 中文字幕一区二区三| 中文字幕在线观看第三页| 久久av电影| 欧美中文字幕第一页| 人成在线免费视频| 色偷偷成人一区二区三区91| 毛片网站免费观看| 久久精品日产第一区二区| 欧美精品免费观看二区| 三妻四妾的电影电视剧在线观看| 亚洲精品乱码久久久久久按摩观| 国产在线综合网| 99久久精品国产麻豆演员表| aa在线观看视频| 亚洲尤物av| 国产精品美女在线观看| 免费高清在线观看| 欧美一区二区不卡视频| 久操视频免费在线观看| 成人av在线资源网| 国产精品亚洲a| 欧美久久综合网| 成人写真福利网| 欧美人与性动交α欧美精品图片| 亚洲国产精彩中文乱码av在线播放| 国产午夜福利一区二区| 久久综合狠狠综合久久综合88| 亚洲一区二区蜜桃| 艳女tv在线观看国产一区| 福利精品视频| 欧美xxx视频| 久久精品国产一区二区电影| 成人午夜免费福利| 日韩欧美大尺度| 国产一区二区三区视频播放| 国产激情91久久精品导航| 精品久久久久久久久久中文字幕| 久久综合色占| 91久久国产综合久久91精品网站| 9999在线视频| 在线日韩第一页| www.综合色| 欧美性生交xxxxx久久久| 永久免费看片直接| av男人天堂一区| 天堂一区在线观看| 在线播放亚洲| 亚洲精品电影在线一区| 高清精品视频| 国产精品一二三视频| 丁香花视频在线观看| 国产一区二区动漫| 亚洲精品久久久久久无码色欲四季 | 免费看91视频| 奇米影视在线99精品| 欧美图片激情小说| 久久亚洲国产| 看高清中日韩色视频| 精品视频国内| 国产免费久久av| 久久男人天堂| 欧美精品在线播放| 91.xxx.高清在线| 亚洲精品久久在线| 亚洲av无码国产精品永久一区| 91精品福利视频| 国产精彩视频在线观看| 国产精品护士白丝一区av| 欧美做受喷浆在线观看| 国产经典欧美精品| 亚洲精品永久视频| 日韩电影免费在线观看网站| 国产一级不卡视频| 国产精品88久久久久久| 日本一区二区三区免费看| 精品女人视频| 粉嫩高清一区二区三区精品视频| 日韩电影精品| 国产精品久久久久久久久久久久| 僵尸再翻生在线观看| 久久精品国产精品亚洲| av电影在线网| 一区二区三区 在线观看视| 人成免费电影一二三区在线观看| 精品少妇一区二区三区在线播放| 中文字幕在线观看精品| 在线影院国内精品| 亚洲婷婷综合网| 精品久久久久久久久中文字幕 | 欧美另类综合| 久久久无码中文字幕久...| 99视频精品全国免费| 亚洲一区二区三区加勒比 | 国产精品久久久久久av公交车| 国产精品极品尤物在线观看 | 在线精品国精品国产尤物884a| 亚洲精品国产精品乱码| 亚洲国产精品一区二区久久| 久久久久久久久久久网| 亚洲伊人伊色伊影伊综合网| 欧美黄片一区二区三区| 亚洲精品免费视频| 欧美精品乱码视频一二专区| 亚洲欧美激情一区二区| 日韩国产第一页| 亚洲激情校园春色| 国产一级一片免费播放| 亚洲高清在线视频| 日韩美女黄色片| 欧美日韩国产一中文字不卡 | 欧美日韩国产大片| 国产精品女同一区二区| 日韩视频免费观看高清完整版在线观看 | 日韩精品久久久久久福利| 手机看片福利在线观看| 亚洲美女久久久| av在线二区| 久久精品最新地址| 日本性爱视频在线观看| 91精品国产高清久久久久久| 一区二区电影免费观看| 国产精品久久激情| 91麻豆精品国产91久久久更新资源速度超快| 成人国产精品一区二区| 亚洲经典视频| 国产伦精品一区二区| 最新精品国偷自产在线| 亚洲精品二区| 欧美午夜电影在线观看| 欧美一区二区三区爽大粗免费 | 午夜影院免费观看视频| 高清不卡一二三区| 黄色a一级视频| 中文无字幕一区二区三区| 成熟的女同志hd| 欧美视频裸体精品| 中文字幕精品一区二| 日韩欧美一级片| 欧美视频综合| 久久艳片www.17c.com| 狠狠操一区二区三区| 国产精品入口福利| 一区中文字幕电影| 五月婷婷综合色| 亚洲国产黄色| 久久国产这里只有精品| 9人人澡人人爽人人精品| 激情五月深爱五月| 午夜一区二区三区视频| 国产成人精品一区二区色戒| 欧美zozo另类异族| 第一页在线观看| 国内精品久久久久影院优 | 日本不卡中文字幕| 精人妻一区二区三区| 中文无字幕一区二区三区| 日韩欧美亚洲视频| 69av一区二区三区| 邻居大乳一区二区三区| 欧美精品videos另类日本| 精品福利在线| 欧美成ee人免费视频| 欧美在线观看天堂一区二区三区| 无码人妻丰满熟妇区毛片| 懂色av一区二区三区蜜臀 | 欧美国产专区| 91人人澡人人爽人人精品| 99久久久国产精品免费蜜臀| 亚洲天堂网av在线| 91福利视频久久久久| 日本波多野结衣在线| 久久成人免费视频| 成人交换视频| 日韩av一区二区三区在线| 国产一区二区高清| 特级特黄刘亦菲aaa级| 亚洲少妇中出一区| 一道本无吗一区| 中国人与牲禽动交精品| 成人爽a毛片免费啪啪| 国产精品手机视频| 国产一在线精品一区在线观看| 亚洲va在线va天堂va偷拍| 国产视频一区二区在线| 二区视频在线观看| 亚洲加勒比久久88色综合| 欧美巨大xxxx做受沙滩| 91深夜福利视频| 国产精品久久久久蜜臀| 91国内在线播放| 国产精品欧美一区喷水| 中文字幕乱码视频| 亚洲图片在线综合| 成人黄色免费短视频| 欧美日本国产精品| 久久看片网站| 91久久免费视频| 日本久久精品电影| 岛国在线大片| 国产精品嫩草影院一区二区| 一区二区三区韩国免费中文网站| 国产一区二区网| av在线综合网| 中文字幕在线欧美| 亚洲视频777| 精品视频在线一区二区在线| 亚洲成色最大综合在线| 久久机这里只有精品| frxxee中国xxx麻豆hd| 91精品麻豆日日躁夜夜躁| a级毛片免费观看在线| 91手机在线播放| 在线观看不卡| v天堂中文在线| 色偷偷久久人人79超碰人人澡| 国产福利在线看| 成人欧美一区二区三区黑人| 欧美区国产区| 亚洲欧美在线不卡| 色婷婷久久久综合中文字幕| 超碰免费97在线观看| 成人在线小视频| 亚洲特级毛片| 四虎永久免费影院| 欧美少妇xxx| 天堂va在线| 久久久亚洲综合网站| 奇米精品一区二区三区在线观看 | 国产精品一区二区三区免费| 久久国产精品亚洲77777| 日本美女bbw| 日韩一区二区麻豆国产| 免费h视频在线观看| 色综合666| 国产成人精品免费在线| 欧美h在线观看| 久久精品视频va| 九九热hot精品视频在线播放| 国产无套内射久久久国产| 国产精品久久久久久久久图文区| 超碰在线人人干| 国产成人一区三区| 欧美日韩a区| 五月天精品视频| 日韩久久精品一区| 成人涩涩视频| 成人精品视频在线播放| 国产精品三级av| 天堂国产一区二区三区| 国产日本欧美视频| 国产精品视频久久一区| 日本黄色片免费观看| 亚洲欧美日韩爽爽影院| 2020国产精品极品色在线观看| 日本新janpanese乱熟| 亚洲一区二区三区中文字幕在线|