當前線程調用目標線程 join() 進入阻塞,直到目標線程終止。適用於「主線程依賴子線程結果」場景。
public class Test2 {
public static void main(String[] args) throws InterruptedException {
System.out.println("當前線程:" + Thread.currentThread().getName());
A a = new A();
Thread t1 = new Thread(a, "被join線程");
t1.start(); // 先 start,後 join
t1.join(); // 主線程等待 t1 結束
System.out.println("主線程執行結束"); // t1 結束後才執行
}
}
class A implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " 輸出:" + i);
}
}
}
重載: join() 無限等待 / join(long millis) 毫秒級 / join(long millis, int nanos) 納秒級。
setDaemon(true) 必須在 start() 前調用,否則拋出 IllegalThreadStateExceptionThread t = new Thread(new A(), "守護線程");
t.setDaemon(true); // start 前調用
t.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " output:" + i);
}
// 主線程結束後,守護線程雖未跑完也被強制終止
| 特性 | sleep() | yield() |
|---|---|---|
| 狀態轉換 | 運行 → 阻塞 → 就緒 | 運行 → 就緒 |
| 鎖行為 | 不釋放鎖 | 不釋放鎖 |
| 調度影響 | 喚醒後所有同優先級線程競爭 | 僅讓同/高優先級線程執行 |
| 異常 | 聲明 InterruptedException | 無 |
| 可移植性 | 強 | 弱,不建議控制併發 |
System.out.println("當前時間:" + new Date());
Thread.sleep(3000);
System.out.println("當前時間:" + new Date());
// 主線程暫停 3 秒
class A extends Thread {
public void run() {
for (int i = 1; i < 10; i++) {
System.out.println(getName() + " 輸出:" + i);
if (i == 3) { Thread.yield(); }
}
}
}
// 低/中優先級線程 yield 後,高優先級線程搶佔 CPU
MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10setPriority() 設置,getPriority() 獲取Thread(ThreadGroup, Runnable) 等ThreadGroup 核心方法:| 方法 | 說明 |
|---|---|
activeCount() | 活躍線程數 |
interrupt() | 中斷組內所有線程 |
setDaemon(boolean) | 設置守護線程組(最後線程死則組銷毀) |
setMaxPriority(int) | 限制組內最大優先級 |
注意:守護線程組 ≠ 組內線程皆為守護線程,兩者無強綁定。
ThreadGroup tg = new ThreadGroup("守護線程組");
tg.setDaemon(true);
A a = new A(tg, "守護線程組的線程A");
a.start();
class A extends Thread {
A(ThreadGroup group, String name) { super(group, name); }
public void run() {
System.out.println("線程:" + getName() + ";組:" + getThreadGroup().getName() + ";守護?" + isDaemon());
}
}
輸出: 組為守護,但線程 isDaemon()=false —— 組屬性不自動傳遞給線程。
System.out.println(Thread.currentThread());
// 輸出:Thread[main,5,main] → 名稱、優先級、組名