1. 程式人生 > >Java多線程_wait/notify/notifyAll方法

Java多線程_wait/notify/notifyAll方法

tro tar ron ava void eth 當前 inf 分享圖片

關於這三個方法,我們可以查詢API得到下列解釋:

wait():導致當前的線程等待,直到其他線程調用此對象的notify( ) 方法或 notifyAll( ) 方法或者指定的事件用完

notify():喚醒在此對象監視器上等待的單個線程

notifyAll():喚醒在此對象監視器上等待的所有線程

我們需要註意的點
(1)wait()、notify/notifyAll() 方法是Object的本地final方法,無法被重寫。

(2)wait() 與 notify/notifyAll 方法必須在同步代碼塊中使用。

(3)由於 wait() 與 notify/notifyAll() 是放在同步代碼塊中的,因此線程在執行它們時,肯定是進入了臨界區中的,即該線程肯定是獲得了鎖的。


(4)當線程執行wait()時,會把當前的鎖釋放,然後讓出CPU,進入等待狀態。

(5)當執行notify/notifyAll方法時,會喚醒一個處於等待該 對象鎖 的線程,然後繼續往下 執行,直到執行完退出對象鎖鎖住的區域(synchronized修飾的代碼塊)後再釋放鎖。

(6)如果在執行wait() 與 notify/notifyAll() 之前沒有獲得相應的對象鎖,就會拋出:java.lang.IllegalMonitorStateException異常。

下面我們看代碼:

public class WaitNotifyDemo {
    public static void main(String[] args) {
        Object lock 
= new Object(); WaitMathodThread w = new WaitMathodThread(lock); w.start(); NotifyMethodThread n = new NotifyMethodThread(lock); n.start(); } public void waitMethod(Object lock) { try { synchronized (lock) { System.out.println(
"begin wait() ThreadName=" + Thread.currentThread().getName()); lock.wait(); System.out.println(" end wait() ThreadName=" + Thread.currentThread().getName()); } } catch (InterruptedException e) { e.printStackTrace(); } } public void notifyMethod(Object lock) { try { synchronized (lock) { System.out.println("begin notify() ThreadName=" + Thread.currentThread().getName() + " time=" + System.currentTimeMillis()); lock.notify(); Thread.sleep(5000); System.out.println(" end notify() ThreadName=" + Thread.currentThread().getName() + " time=" + System.currentTimeMillis()); } } catch (InterruptedException e) { e.printStackTrace(); } } } class WaitMathodThread extends Thread { private Object lock; public WaitMathodThread(Object lock) { super(); this.lock = lock; } @Override public void run() { WaitNotifyDemo wnd = new WaitNotifyDemo(); wnd.waitMethod(lock); } } class NotifyMethodThread extends Thread { private Object lock; public NotifyMethodThread(Object lock) { super(); this.lock = lock; } @Override public void run() { WaitNotifyDemo wnd = new WaitNotifyDemo(); wnd.notifyMethod(lock); } }

運行結果:

技術分享圖片

從這個測試中可以看出調用了wait()方法後會立即釋放鎖,線程進入等待狀態,而調用了notify()方法後並不會立即釋放鎖,會等到走完synchronized修飾的臨界區時,才會釋放鎖。
所以一般在調用了notify()方法後最好馬上退出synchronized修飾的臨界區。

Java多線程_wait/notify/notifyAll方法