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

Java 線程核心機制深度解析:join、守護線程、睡眠、讓步與優先級

     編輯:Java 相關知識

前言

在 Java 並發編程中,線程控制是核心基石。本文將系統講解 join()、守護線程、sleep()、yield() 以及線程優先級這五大關鍵機制,並附帶完整代碼示例,助你掌握線程協作與調度的精髓。

一、join():線程等待與合併

核心概念

join() 允許一個線程等待另一個線程執行完畢。常見場景:主線程將大任務拆分為多個子線程並行執行,需等所有子線程完成後再匯總結果。

三種重載形式

  • join():無限期等待目標線程結束
  • join(long millis):最多等待指定毫秒數
  • join(long millis, int nanos):精確到納秒級等待(極少使用)

代碼示例

public class JoinDemo extends Thread {
    public JoinDemo(String name) { super(name); }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + " " + i);
        }
    }

    public static void main(String[] args) {
        new JoinDemo("子線程-A").start();
        for (int i = 0; i < 100; i++) {
            if (i == 20) {
                JoinDemo jt = new JoinDemo("被join線程");
                jt.start();
                try { jt.join(); }  // 主線程阻塞,直到 jt 結束
                catch (InterruptedException e) { e.printStackTrace(); }
            }
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

執行現象:當 i=20 時主線程阻塞,僅剩「子線程-A」與「被join線程」並行;待後者結束,主線程才恢復執行。

二、守護線程:默默奉獻的後台衛士

特性

  • 為其他線程提供服務(如 GC、JIT 編譯)
  • 所有用戶線程(前台線程)結束時,JVM 自動終止守護線程
  • 默認情況:main 線程是用戶線程;用戶線程創建的子線程默認也是用戶線程;守護線程創建的子線程默認是守護線程

代碼示例

public class DaemonDemo extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(getName() + " " + i);
        }
    }

    public static void main(String[] args) {
        DaemonDemo dt = new DaemonDemo();
        dt.setDaemon(true);  // 設置為守護線程
        dt.start();
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
        // main 結束 → 守護線程 dt 強制終止,無法跑完 1000 次循環
    }
}

三、sleep():定時休眠

與 join() 的區別

sleep() 讓**當前線程**進入阻塞狀態指定時間,然後回到就緒狀態等待調度;不釋放鎖。常用於定時任務、限流等場景。

重載方法

  • sleep(long millis):毫秒級休眠
  • sleep(long millis, int nanos):納秒級補充(極少用)

注意:實際休眠時間受系統計時器精度影響,可能超過指定時間。

代碼示例

public class SleepDemo {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            System.out.println("當前時間:" + new Date());
            try { Thread.sleep(1000); }
            catch (InterruptedException e) { e.printStackTrace(); }
        }
    }
}

四、yield():禮讓 CPU

機制

  • 將當前線程從「運行態」轉為「就緒態」,**不進入阻塞態**
  • 僅讓**同優先級或更高優先級**的線程獲得執行機會
  • 當前線程可能立即被再次調度繼續執行

代碼示例

public class YieldDemo extends Thread {
    public YieldDemo(String name) { super(name); }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(getName() + " " + i);
            if (i == 20) Thread.yield();  // 禮讓
        }
    }

    public static void main(String[] args) {
        YieldDemo high = new YieldDemo("高優先級");
        high.setPriority(Thread.MAX_PRIORITY);
        high.start();

        YieldDemo low = new YieldDemo("低優先級");
        low.setPriority(Thread.MIN_PRIORITY);
        low.start();
        // 高優先級線程 yield 時,不會讓給低優先級線程
    }
}

五、線程優先級:調度的參考依據

規則

  • 範圍 1~10,默認 5 (NORM_PRIORITY)
  • 三個常量:MAX_PRIORITY(10)、MIN_PRIORITY(1)、NORM_PRIORITY(5)
  • 子線程繼承父線程優先級
  • 可移植性建議:優先使用常量,避免硬編碼數字,因不同 OS 支持的優先級層級不同

設置示例

thread.setPriority(Thread.MAX_PRIORITY);  // 推薦
// thread.setPriority(10);  // 不推薦

總結

方法狀態轉換釋放鎖典型用途
join()運行→阻塞否線程合併、結果匯總
sleep()運行→阻塞否定時任務、限流
yield()運行→就緒否禮讓 CPU、測試併發
setPriority()無狀態變化否調度提示

掌握這五大機制,配合 synchronized、Lock 等同步工具,即可構建高效、可控的 Java 並發程序。

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