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

Java 多執行緒進階:wait/notify 機制、執行緒優先級、執行緒群組與 SwingUtilities 實務

     編輯:Java 相關知識

前言

Java 物件內建的 wait()、notify()、notifyAll() 是執行緒協作的基石。本文系統整理這組底層 API、執行緒優先級與群組的實務觀點,並補充 Swing/AWT 事件派發執行緒(EDT)的跨執行緒 UI 更新技巧。

一、Object 監視器方法:wait / notify / notifyAll

前置條件

呼叫前必須持有該物件的鎖(在 synchronized 區塊或方法內)。

方法語意

  • wait():釋放鎖,進入等待集合,直到
    • 被 notify()/notifyAll() 喚醒
    • 被 Thread.interrupt() 中斷
    • 超時(wait(long timeout))
    喚醒後重新競爭鎖。
  • notify():隨機喚醒一個等待該物件的執行緒。
  • notifyAll():喚醒所有等待該物件的執行緒。

最佳實踐

  1. 永遠在 while 迴圈中檢查條件,防止虛假喚醒:
    synchronized (lock) {
        while (!condition) {
            lock.wait();
        }
        // 執行關鍵區段
    }
    
  2. 預設使用 notifyAll()。僅在確定等待集合中所有執行緒條件相同、且喚醒任一個即可滿足後續邏輯時,才考慮 notify()(效能優化,風險較高)。
  3. 不要自行造輪子:生產環境請直接使用 java.util.concurrent 套件(BlockingQueue、CountDownLatch、Semaphore、ReentrantLock、Condition 等),JDK 1.5+ 已內建。

二、執行緒優先級

  • Thread.setPriority(int) 範圍 1(MIN)~ 10(MAX),預設 5(NORM)。
  • 映射至 OS 排程器視實作而定:多個 Java 優先級可能對應同一 OS 優先級,不可倚賴精確調度。
  • 避免調整優先級解決死結/飢餓:通常只是將問題轉移。正解在於鎖粒度縮減、無鎖資料結構、公平鎖或架構重構。

三、執行緒群組

  • ThreadGroup 設計初衷為階層式管理,但功能薄弱(stop()、suspend()、resume() 已棄用)。
  • 唯一實用方法:uncaughtException(Thread t, Throwable e) — 可覆寫實作全域例外處理(記錄、重啟服務、關閉系統)。
  • 建議:直接使用 Thread 同等方法,不依賴 ThreadGroup。

四、SwingUtilities:跨執行緒更新 UI

核心規則

所有 Swing 元件建立、狀態變更、繪圖必須在事件派發執行緒(EDT)執行。

兩大靜態方法

方法行為適用場景
invokeLater(Runnable)非阻塞,將任務排入 EDT 佇列稍後執行背景執行緒觸發 UI 更新、記錄日誌、啟動對話框
invokeAndWait(Runnable)阻塞呼叫執行緒,直到 EDT 完成任務需要取得 UI 回傳值、同步等待對話框關閉

範例:背景執行緒安全顯示對話框

void showHelloThereDialog() {
    Runnable task = () -> JOptionPane.showMessageDialog(mainFrame, "Hello There");
    SwingUtilities.invokeLater(task); // 非阻塞
}

AWT 相容

java.awt.EventQueue.invokeLater/AndWait 功能相同,適用於純 AWT 專案。

五、總結對照表

主題關鍵點建議
wait/notify需持有鎖、while 迴圈檢查條件、優先 notifyAll改用 java.util.concurrent 高階工具
優先級平台相依、不可倚賴保持預設,專注鎖設計
ThreadGroup功能殘缺、僅 uncaughtException 有用不使用,改用 Thread.setDefaultUncaughtExceptionHandler
SwingUtilitiesEDT 單執行緒規則、invokeLater/AndWait所有跨執行緒 UI 操作必須委派

結語

掌握 wait/notify 底層語意有助於理解高階並發工具原理,但實務開發請拥抱 java.util.concurrent。執行緒優先級與群組屬於「了解即可、勿深度依賴」範疇。Swing/AWT 開發者務必內化 EDT 規則,善用 SwingUtilities 避免競態條件與凍結介面。

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