Thread.join解析

Blocks the current Thread (<code>Thread.currentThread()</code>) until the receiver finishes its execution and dies.
@throws InterruptedException if <code>interrupt()</code> was called for the receiver while it was in the <code>join()</code> call
@see Object#notifyAll
@see java.lang.ThreadDeath

join方法的注釋上寫著:阻塞當前線程,直到收到結束執行或者死亡。當接收者的interrupt方法被調用,并且它被調用了join方法的時候,就會拋出InteruptedException。
舉個例子:線程A的run方法中調用了線程B的join,此時線程A處于阻塞狀態,直到線程B執行完畢或者死亡的時候,線程A才會繼續執行。如果此時線程A處于阻塞狀態,而線程B調用線程A的interrupt的時候,就會拋出InterruptedException。
下面舉兩個例子
示例1:
有兩個線程A,B,在A的run方法中,會調用ThreadB.join,也就是說,在ThreadA啟動之后,打印出來"ThreadA Started"之后,就會被線程B阻塞。然后線程B開始執行,打印出來"ThreadB started"之后,會休眠5S,之后再打印出"ThreadB Sleep End",之后線程B執行結束,于是線程A阻塞解除,打印出"ThreadA End"。

public class Test {
public static void main(String[] args) {
    ThreadB threadB = new ThreadB();
    ThreadA threadA = new ThreadA(threadB);
    threadA.start();
    threadB.start();
}

private static class ThreadA extends Thread {
    ThreadB joinThread;

    ThreadA(ThreadB threadB) {
        joinThread = threadB;
    }

    @Override
    public void run() {
        super.run();
        System.out.println("ThreadA Started");
        try {
            joinThread.join();
        } catch (InterruptedException e) {
        }
        System.out.println("ThreadA End");
    }
}

private static class ThreadB extends Thread {
    @Override
    public void run() {
        super.run();
        System.out.println("ThreadB started");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ThreadB Sleep End");
    }
}
}

運行結果:

示例1結果

示例2
和上例不一樣的地方是,在ThreadB的Run方法中,Sleep完后,調用ThreadA.interrupt,試一下官方文檔上注釋對不對。

public class Test {
public static void main(String[] args) {
    ThreadB threadB = new ThreadB();
    ThreadA threadA = new ThreadA(threadB);
    threadB.setThreadA(threadA);
    threadA.start();
    threadB.start();
}

private static class ThreadA extends Thread {
    ThreadB joinThread;

    ThreadA(ThreadB threadB) {
        joinThread = threadB;
    }

    @Override
    public void run() {
        super.run();
        System.out.println("ThreadA Started");
        try {
            joinThread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ThreadA End");
    }
}

private static class ThreadB extends Thread {
    ThreadA threadA;

    public void setThreadA(ThreadA threadA) {
        this.threadA = threadA;
    }

    @Override
    public void run() {
        super.run();
        System.out.println("ThreadB started");
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("ThreadB Call ThreadA.interrupt");
        threadA.interrupt();
        System.out.println("ThreadB Sleep End");
    }
}
}

運行結果:
打印出InterruptedException

示例2運行結果
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Java多線程學習 [-] 一擴展javalangThread類 二實現javalangRunnable接口 三T...
    影馳閱讀 2,987評論 1 18
  • 該文章轉自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍閱讀 7,381評論 3 87
  • 本文主要講了java中多線程的使用方法、線程同步、線程數據傳遞、線程狀態及相應的一些線程函數用法、概述等。 首先講...
    李欣陽閱讀 2,503評論 1 15
  • 寫在前面的話: 這篇博客是我從這里“轉載”的,為什么轉載兩個字加“”呢?因為這絕不是簡單的復制粘貼,我花了五六個小...
    SmartSean閱讀 4,792評論 12 45
  • 1、什么是委托 委托可以理解為持有一個或多個方法的對象。如果執行委托的話,委托會 執行它所"持有"的方法。委托可以...
    小明yz閱讀 720評論 0 2