首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 線程 join() 等待機制原理與實戰

     編輯:Java 相關知識

join() 作用

thread.join() 讓呼叫線程(通常是主線程)等待目標線程執行結束後才繼續。本質是呼叫線程在目標線程的 join() 方法內循環調用 wait()。

源碼剖析 (JDK 1.7)

public final void join() throws InterruptedException { join(0); }
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;
        }
    }
}

關鍵點:wait() 讓當前執行線程(主線程)進入等待,而非目標線程。

實戰範例

public class JoinTest {
    public static void main(String[] args) {
        try {
            ThreadA t1 = new ThreadA("t1");
            t1.start();
            t1.join(); // 主線程阻塞直到 t1 結束
            System.out.printf("%s finish%n", Thread.currentThread().getName());
        } catch (InterruptedException e) { e.printStackTrace(); }
    }
    static class ThreadA extends Thread {
        @Override public void run() {
            System.out.printf("%s start%n", getName());
            for (int i = 0; i < 1_000_000; i++); // 模擬耗時
            System.out.printf("%s finish%n", getName());
        }
    }
}

執行流程

t1 start
t1 finish
main finish
  1. 主線程啟動 t1,呼叫 t1.join() 進入阻塞。
  2. t1 執行結束,JVM 喚醒主線程。
  3. 主線程繼續印出 main finish。

常見誤區

誤以為 t1.join() 是讓 t1 等待。實際上 join() 是 Thread 實例方法,但內部 wait() 作用於呼叫者(主線程)。

帶超時的 join

t1.join(2000) 最多等待 2 秒,超時後主線程自動繼續,不拋異常。需配合 t1.isAlive() 判斷是否正常結束。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved