線程阻塞(四),join及源碼解析

有一個筆試題卵酪,A幌蚊、B、C三個線程溃卡,怎么保證A執(zhí)行完后再執(zhí)行B溢豆,B執(zhí)行完后再執(zhí)行C。

最簡單的就是join 了吧瘸羡。直接上代碼:

public static void main(String[] args) throws InterruptedException {
        PrintThread threadA = new PrintThread("Thread A");
        PrintThread threadB = new PrintThread("Thread B");
        PrintThread threadC = new PrintThread("Thread C");
        threadA.start();
        threadA.join();
        threadB.start();
        threadB.join();
        threadC.start();
    }

    static class PrintThread extends Thread {
        PrintThread(String name) {
            super(name);
        }

        @Override
        public void run() {
            System.out.println(getName() + " start");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(getName() + " end ...");
        }
    }

執(zhí)行結(jié)果:

Thread A start
Thread A end ...
Thread B start
Thread B end ...
Thread C start
Thread C end ...

那么join是怎么實(shí)現(xiàn)的呢漩仙?看下源碼:

  /**
     * Waits for this thread to die.
     *
     * <p> An invocation of this method behaves in exactly the same
     * way as the invocation
     *
     * <blockquote>
     * {@linkplain #join(long) join}{@code (0)}
     * </blockquote>
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final void join() throws InterruptedException {
        join(0);
    }

注意下注釋:等待此線程執(zhí)行完。

join()方法實(shí)際上調(diào)用了join(long millis),參數(shù)是0,再往下看:

    /**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

翻譯一下注釋:等待millis 毫秒終止線程队他,假如這段時間內(nèi)該線程還沒執(zhí)行完卷仑,那么結(jié)束等待。如果是0麸折,意味著一直等待锡凝,知道線程終止。

很明顯垢啼,有一個while循環(huán)使該線程一直停留在阻塞狀態(tài)窜锯,再看一下isAlive()方法:

 /**
     * Tests if this thread is alive. A thread is alive if it has
     * been started and has not yet died.
     *
     * @return  <code>true</code> if this thread is alive;
     *          <code>false</code> otherwise.
     */
    public final native boolean isAlive();

是一個native方法,但是看一下注釋:判斷該線程是否是正在執(zhí)行狀態(tài)芭析,正在執(zhí)行狀態(tài)是指已經(jīng)start了锚扎,但是還沒結(jié)束。

通過不停判斷該線程的狀態(tài)馁启,來決定是不是要wait驾孔,線程結(jié)束,或者達(dá)到指定的延遲時間后进统,終止代碼助币。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市螟碎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迹栓,老刑警劉巖掉分,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異克伊,居然都是意外死亡酥郭,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門愿吹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來不从,“玉大人,你說我怎么就攤上這事犁跪〈幌ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵坷衍,是天一觀的道長寝优。 經(jīng)常有香客問我,道長枫耳,這世上最難降的妖魔是什么乏矾? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上钻心,老公的妹妹穿的比我還像新娘凄硼。我一直安慰自己,他們只是感情好捷沸,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布帆喇。 她就那樣靜靜地躺著,像睡著了一般亿胸。 火紅的嫁衣襯著肌膚如雪坯钦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天侈玄,我揣著相機(jī)與錄音婉刀,去河邊找鬼。 笑死序仙,一個胖子當(dāng)著我的面吹牛突颊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播潘悼,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼律秃,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了治唤?” 一聲冷哼從身側(cè)響起棒动,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎宾添,沒想到半個月后船惨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缕陕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年粱锐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛邑。...
    茶點(diǎn)故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡怜浅,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔬崩,到底是詐尸還是另有隱情恶座,我是刑警寧澤,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布舱殿,位于F島的核電站奥裸,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏沪袭。R本人自食惡果不足惜湾宙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一樟氢、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧侠鳄,春花似錦埠啃、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至博秫,卻和暖如春潦牛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挡育。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工巴碗, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人即寒。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓橡淆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親母赵。 傳聞我的和親對象是個殘疾皇子逸爵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,870評論 2 361

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