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

Java 多線程控制藝術:join、守護線程、sleep/yield、優先級與線程組實戰

     編輯:Java 相關知識

1. join():等待線程完成

當前線程調用目標線程 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) 納秒級。

2. 守護線程(Daemon Thread)

  • 所有用戶線程(非守護)結束 → JVM 退出,守護線程強制終止
  • 用戶線程創建的子線程默認用戶線程;守護線程創建的子線程默認守護線程
  • setDaemon(true) 必須在 start() 前調用,否則拋出 IllegalThreadStateException
Thread 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);
}
// 主線程結束後,守護線程雖未跑完也被強制終止

3. sleep() 與 yield() 對比

特性sleep()yield()
狀態轉換運行 → 阻塞 → 就緒運行 → 就緒
鎖行為不釋放鎖不釋放鎖
調度影響喚醒後所有同優先級線程競爭僅讓同/高優先級線程執行
異常聲明 InterruptedException無
可移植性強弱,不建議控制併發

sleep 示例

System.out.println("當前時間:" + new Date());
Thread.sleep(3000);
System.out.println("當前時間:" + new Date());
// 主線程暫停 3 秒

yield 示例

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

4. 線程優先級

  • 範圍 1-10,常量:MIN_PRIORITY=1、NORM_PRIORITY=5、MAX_PRIORITY=10
  • setPriority() 設置,getPriority() 獲取
  • 子線程默認繼承父線程優先級
  • 建議使用常量,提高可移植性

5. 線程組:批量管理線程

  • 每個線程屬於一個線程組,默認繼承父線程組
  • 構造器指定組: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 —— 組屬性不自動傳遞給線程。

6. 線程狀態查看

System.out.println(Thread.currentThread());
// 輸出:Thread[main,5,main] → 名稱、優先級、組名
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved