Python & Java 多線程Join方法

join 是Thread 的方法。

import time, threading

# 假定這是你的銀行存款:
balance = 0

def change_it(n):
    # 先存后取,結果應該為0:
    global balance
    balance = balance + n
    balance = balance - n

def run_thread(n):
    for i in range(100000):
        change_it(n)

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

阻塞當前線程,等待到該線程結束,才開始執行后面語句。
Join之后類似于Java,似乎變成單線程了。

Java 的Join

thread.Join把指定的線程加入到當前線程,可以將兩個交替執行的線程合并為順序執行的線程。比如在線程B中調用了線程A的Join()方法,直到線程A執行完畢后,才會繼續執行線程B。

thread.join(1000); 也可以調用join時候加上一個超時參數,如果目標線程在這段時間到期時候還沒有結束的話,join方法總能返回。

join 源碼

 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;
            }
        }
    }

join 方法是synchronized 修飾的,且調用對象是thread,所以當main線程調用t.join時,main線程會獲得線程對象t的鎖(哪個線程調用synchronized方法 哪個線程獲得鎖,而此處是對象Thread t的對象鎖[join是Thread的方法 ])
調用該對象t的wait(等待時間),直到該對象t喚醒main線程 ,比如退出后。

public class Test {
    public static void main(String[] args) {
        
        Thread thread1 = new Thread(){
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                    System.out.println("thread handle 1");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        
        Thread thread2 = new Thread(){
            public void run() {
                try {
                    System.out.println(Thread.currentThread().getName());
                    Thread.sleep(1000);
                    System.out.println("thread handle 2");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        
        thread1.start();
        thread2.start();
        
        try {
            thread1.join();
            System.out.println("==============>");
            thread2.join();
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("end");
        
    }
}

為了更清楚的看到結果,可以更改兩個線程的Thread休眠時間。

執行結果有3種:

Thread-0
Thread-1
thread handle 1
thread handle 2
==============>
end

Thread-0
Thread-1
thread handle 1
==============>
thread handle 2
end

Thread-0
Thread-1
thread handle 2
thread handle 1
==============>
end

可以看出2個線程同時啟動,但是結束的順序不一定
如 情況一

Thread0.join() start
Thread0首先執行完
Thread0.join() end
輸入 =======> 
Thread1.join() start
Thread1 執行完
Thread1.join() end
System.out.println("end")

情況二

Thread0.join() start
Thread1首先執行完
Thread0執行完
Thread0.join() end
輸入 =======> 
Thread1.join() start  (isAlive = false 的直接跳過阻塞)
Thread1.join() end
System.out.println("end")

情況三

Thread0.join() start
Thread0首先執行完
Thread1執行完 (2個線程幾乎同時執行完至少比Thread0.join()快)
Thread0.join() end
輸入 =======> 
Thread1.join() start  (isAlive = false 的直接跳過阻塞)
Thread1.join() end
System.out.println("end")
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Java多線程學習 [-] 一擴展javalangThread類 二實現javalangRunnable接口 三T...
    影馳閱讀 2,986評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數據傳遞、線程狀態及相應的一些線程函數用法、概述等。 首先講...
    李欣陽閱讀 2,493評論 1 15
  • 該文章轉自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍閱讀 7,380評論 3 87
  • Java-Review-Note——4.多線程 標簽: JavaStudy PS:本來是分開三篇的,后來想想還是整...
    coder_pig閱讀 1,673評論 2 17
  • 寫在前面的話: 這篇博客是我從這里“轉載”的,為什么轉載兩個字加“”呢?因為這絕不是簡單的復制粘貼,我花了五六個小...
    SmartSean閱讀 4,789評論 12 45