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

Java Object.wait() 與 notify() 完整解析與正確用法

     編輯:Java 相關知識

wait()、notify()、notifyAll() 是 Object 類的 final native 方法,無法被子類覆寫。這三個方法必須在同步方法或同步區塊(synchronized)中呼叫,且當前線程必須持有該物件的鎖,否則會拋出 IllegalMonitorStateException。

方法詳解

  • wait():讓當前線程進入等待狀態,直到被 notify() 或 notifyAll() 喚醒
  • wait(long millis) / wait(long millis, int nanos):帶超時的等待,超時自動喚醒
  • notify():隨機喚醒一個在該物件上等待的線程
  • notifyAll():喚醒所有在該物件上等待的線程

三種呼叫方式

由於這些方法定義在 Object 類中,可透過以下三種方式呼叫:

wait();        // 方式1
this.wait();   // 方式2
super.wait();  // 方式3

常見錯誤示範

在 synchronized 方法外呼叫 wait() 會拋出異常:

public class ObjectWaitTest {
    public static void main(String args[]) {
        A a = new A();
        try {
            a.printThreadInfo(); // synchronized 方法
            a.wait(); // 錯誤!不在 synchronized 區塊中
        } catch (InterruptedException e) { e.printStackTrace(); }
    }
}

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
    }
}

執行結果:IllegalMonitorStateException

正確寫法

將 wait() 放入 synchronized 方法內部:

class A {
    public synchronized void printThreadInfo() throws InterruptedException {
        Thread t = Thread.currentThread();
        System.out.println("ThreadID:" + t.getId() + ", ThreadName:" + t.getName());
        this.wait(1000); // 正確:在 synchronized 方法中呼叫
    }
}

主線程呼叫後,釋放鎖並等待 1000ms,其他線程可進入同步方法。

關鍵要點總結

  1. wait()/notify() 必須在 synchronized 方法或區塊內呼叫
  2. 當前線程必須持有物件鎖
  3. wait() 會釋放鎖,notify() 不釋放鎖(直到同步區塊結束)
  4. 使用 wait(long timeout) 可避免無限期等待造成死鎖
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved