Java多線程中,wait()和join()的區(qū)別痰催,帶你入門不放棄

前述

面試過的小伙伴兜辞,應(yīng)該都被問到過這個(gè)問題。估計(jì)被問蒙蒙的不少 :-D
今天我們可以一起來分析一下夸溶,文章不長(zhǎng)逸吵,相信你通過這一篇文章,就可以有很好的掌握了蜘醋!

一胁塞、方法的歸屬

  • wait()方法是object類的方法
  • join()是Thread的方法咏尝。

二压语、 不正經(jīng)的解釋

  • wait()我要休息一會(huì),我累了


  • join()老子要插隊(duì)编检,都NM給我讓開胎食,都等一等


    image

官方一點(diǎn)的說法:

Wait的用法:
當(dāng)一個(gè)線程調(diào)用wait的時(shí)候,會(huì)釋放同步鎖允懂,然后該線程進(jìn)入等待狀態(tài)厕怜。其他掛起的線程會(huì)競(jìng)爭(zhēng)這個(gè)鎖,得到鎖的繼續(xù)執(zhí)行蕾总。

join的用法:
一個(gè)線程運(yùn)行中調(diào)用另外線程的JOIN方法粥航,則當(dāng)前線程停止執(zhí)行,一直等到新join進(jìn)來的線程執(zhí)行完畢生百,才會(huì)繼續(xù)執(zhí)行5萑浮!

join的測(cè)試用例:

一蚀浆、不加join

public class Main{
public static void main(String[] args) {
        System.out.println("Main 線程 開始運(yùn)行!");
         Thread t1 = new Thread(){
             @Override
             public void run(){
                 System.out.println("t1 開始運(yùn)行!");
                 System.out.println("t1 結(jié)束運(yùn)行!");
             }
         };
         t1.start();
         System.out.println("Main 線程 結(jié)束運(yùn)行!");
    }
}

打印結(jié)果為:
Main 線程 開始運(yùn)行!
Main 線程 結(jié)束運(yùn)行!
t1 開始運(yùn)行!
t1 結(jié)束運(yùn)行!

說明主線程執(zhí)行完畢缀程,才執(zhí)行的子線程t1搜吧,這個(gè)大家都懂!

二杨凑、加join

public class Main{
    public static void main(String[] args) {
        System.out.println("Main 線程 開始運(yùn)行!");
         Thread t1 = new Thread(){
             @Override
             public void run(){
                 System.out.println("t1 開始運(yùn)行!");
                 System.out.println("t1 結(jié)束運(yùn)行!");
             }
         };
         try{
             t1.start();
             t1.join();
         }catch(Exception e){
             
         }
         System.out.println("Main 線程 結(jié)束運(yùn)行!");
    }
}

打印結(jié)果為:
Main 線程 開始運(yùn)行!
t1 開始運(yùn)行!
t1 結(jié)束運(yùn)行!
Main 線程 結(jié)束運(yùn)行!

說明t1線程插隊(duì)了滤奈,直到t1運(yùn)行完畢,主線程才繼續(xù)運(yùn)行撩满。
所以我們可以先簡(jiǎn)單理解為join就是新線程插隊(duì)執(zhí)行(當(dāng)前運(yùn)行線程阻塞直到新線程運(yùn)行結(jié)束Q殉獭)

接下里我們拋出問題,然后再來認(rèn)真分析join()的原理鹦牛。

問題1:

上面例子中搞糕,我們把join()和start()調(diào)換個(gè)順序,會(huì)發(fā)現(xiàn)輸出結(jié)果為:

Main 線程 開始運(yùn)行!
Main 線程 結(jié)束運(yùn)行!
t1 開始運(yùn)行!
t1 結(jié)束運(yùn)行!

why曼追?窍仰?
下面我們來分析源碼Thread.java

public final void join(long millis) throws InterruptedException {
        synchronized(lock) {//主線程拿到lock鎖
        long base = System.currentTimeMillis();

        if (millis == 0) {
            while (isAlive()) { //由于該線程已經(jīng)start(),所以視為alive
                lock.wait(0);  
                //主線程釋放鎖,進(jìn)入無限期的等待狀態(tài)礼殊。
               //直到子線程完成run驹吮,釋放鎖,然后主線程會(huì)重新拿到鎖頭繼續(xù)運(yùn)行
               //拿到鎖之后晶伦,isAlive()不成立了碟狞,所以退出while循環(huán)!婚陪!
            }
        } else {
            }
        }
        }
    }

調(diào)用join()時(shí), 默認(rèn)millis為0族沃。
如上代碼,如果沒有先執(zhí)行start()直接執(zhí)行join泌参,則isAlive()返回為false脆淹,則主線程不會(huì)堵塞進(jìn)入wait(0),這就是為什么一定要先start()然后再join()的原因所在沽一。

問題2:

為什么join()可以阻塞主線程盖溺,直到子線程執(zhí)行完畢?铣缠?
同樣看上面代碼:

  • 主線程進(jìn)入join()方法
  • 主線程拿到子線程的lock鎖
  • 進(jìn)入同步代碼快
  • while (isAlive()) 成立烘嘱,因?yàn)橄日{(diào)用了start()方法
  • 調(diào)用 lock.wait(0), 主線程釋放鎖,進(jìn)入wait狀態(tài)
  • 子線程開始執(zhí)行蝗蛙,執(zhí)行結(jié)束會(huì)調(diào)用lock.notifyAll(),通知主線程獲得鎖蝇庭。
  • 主線程重新啟動(dòng), while (isAlive()) 已經(jīng)不成立(由于子線程不再是alive狀態(tài))
  • 主線程繼續(xù)往下運(yùn)行捡硅。

其中倒數(shù)第三部哮内,是在jdk的Thread.cpp里完成的,可以先不做研究!!

image.jpeg

相信到此病曾,你大致了解了一下機(jī)理牍蜂。

總結(jié)與綜述

  • wait是object類的方法
  • join是Thread類的方法
  • Wait的用法:當(dāng)一個(gè)線程調(diào)用wait的時(shí)候漾根,會(huì)釋放同步鎖,然后該線程進(jìn)入等待狀態(tài)鲫竞。其他掛起的線程會(huì)競(jìng)爭(zhēng)這個(gè)鎖辐怕,得到鎖的繼續(xù)執(zhí)行。
  • join的用法:一個(gè)線程A運(yùn)行中調(diào)用線程B.join()方法从绘,則A線程停止執(zhí)行寄疏,一直等到B線程執(zhí)行完畢,A線程才會(huì)繼續(xù)執(zhí)行=┚陕截!
  • join方法的實(shí)現(xiàn),利用了wait()和notifyAll()方法批什。

搞定~~~ 有問題歡迎一起交流

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末农曲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子驻债,更是在濱河造成了極大的恐慌乳规,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件合呐,死亡現(xiàn)場(chǎng)離奇詭異暮的,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)淌实,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門冻辩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人拆祈,你說我怎么就攤上這事恨闪。” “怎么了缘屹?”我有些...
    開封第一講書人閱讀 162,328評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵凛剥,是天一觀的道長(zhǎng)侠仇。 經(jīng)常有香客問我轻姿,道長(zhǎng),這世上最難降的妖魔是什么逻炊? 我笑而不...
    開封第一講書人閱讀 58,147評(píng)論 1 292
  • 正文 為了忘掉前任互亮,我火速辦了婚禮,結(jié)果婚禮上余素,老公的妹妹穿的比我還像新娘豹休。我一直安慰自己,他們只是感情好桨吊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,160評(píng)論 6 388
  • 文/花漫 我一把揭開白布威根。 她就那樣靜靜地躺著凤巨,像睡著了一般。 火紅的嫁衣襯著肌膚如雪洛搀。 梳的紋絲不亂的頭發(fā)上敢茁,一...
    開封第一講書人閱讀 51,115評(píng)論 1 296
  • 那天,我揣著相機(jī)與錄音留美,去河邊找鬼彰檬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛谎砾,可吹牛的內(nèi)容都是我干的逢倍。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼景图,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼较雕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挚币,我...
    開封第一講書人閱讀 38,867評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤郎笆,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后忘晤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宛蚓,經(jīng)...
    沈念sama閱讀 45,307評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,528評(píng)論 2 332
  • 正文 我和宋清朗相戀三年设塔,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了凄吏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,688評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡闰蛔,死狀恐怖痕钢,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情序六,我是刑警寧澤任连,帶...
    沈念sama閱讀 35,409評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站例诀,受9級(jí)特大地震影響随抠,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜繁涂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,001評(píng)論 3 325
  • 文/蒙蒙 一拱她、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧扔罪,春花似錦秉沼、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽矗积。三九已至,卻和暖如春敞咧,著一層夾襖步出監(jiān)牢的瞬間漠魏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評(píng)論 1 268
  • 我被黑心中介騙來泰國打工妄均, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留柱锹,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,685評(píng)論 2 368
  • 正文 我出身青樓丰包,卻偏偏與公主長(zhǎng)得像禁熏,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子邑彪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,573評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 本文主要講了java中多線程的使用方法瞧毙、線程同步、線程數(shù)據(jù)傳遞寄症、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法宙彪、概述等。 首先講...
    李欣陽閱讀 2,454評(píng)論 1 15
  • Java多線程學(xué)習(xí) [-] 一擴(kuò)展javalangThread類 二實(shí)現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,957評(píng)論 1 18
  • 一擴(kuò)展javalangThread類二實(shí)現(xiàn)javalangRunnable接口三Thread和Runnable的區(qū)...
    和帥_db6a閱讀 487評(píng)論 0 1
  • 林炳文Evankaka原創(chuàng)作品有巧。轉(zhuǎn)載自http://blog.csdn.net/evankaka 本文主要講了ja...
    ccq_inori閱讀 654評(píng)論 0 4
  • 一释漆、金句: 1、如何利用規(guī)律和趨勢(shì)篮迎,放大個(gè)人努力男图。2、你根本不需要掌握這本書里說的所有方法甜橱。你真正要做的是一邊實(shí)踐...
    艾白羊閱讀 249評(píng)論 0 0