1. 程式人生 > 其它 >wait & notify

wait & notify

技術標籤:JUC

目錄

1、wait / notify 原理

  • Owner執行緒發現條件不滿足,呼叫wait方法,即可進入WaitSet變為WAITING狀態
  • BLOCKED和WAITING的執行緒都處於阻塞狀態,不佔用CPU時間片
  • BLOCKED執行緒會在Owner執行緒釋放鎖的時候被喚醒
  • WAITING執行緒會在Owner執行緒呼叫notify或notifyAll時喚醒,但喚醒後並不意味著立刻獲得鎖,仍需進入EntryList重新競爭

2、API介紹

  • obj.wait()讓進入object監視器的執行緒到waitSet等待

  • obj.notify()在object上正在waitSet’等待的執行緒中挑一個喚醒

  • obj.notifyAll()讓object上正在waitSet等待的執行緒全部喚醒

他們都是執行緒之間協作的手段,都屬於Object的方法。必須獲得物件的鎖,才能呼叫這幾個方法

當沒有鎖時,丟擲異常

public class WaitAndNotify {
    static final Object Lock = new Object();
    public static void main(String[] args) {
        try {
            Lock.
wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }

正確姿勢

public class WaitAndNotify {
    static final Object Lock = new Object();
    public static void main(String[] args) {
        synchronized (Lock) {
            try {
                Lock.wait
(); } catch (InterruptedException e) { e.printStackTrace(); } } } }

3、練習

package com.sharing_model.wait_notify;

/**
 * wait notify 正確使用
 */
public class WaitAndNotifyTrueUse {
    static final Object room = new Object();
    static boolean hasCigarette = false;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            System.out.println("有煙沒?" + hasCigarette);
            synchronized (room) {
                if (!hasCigarette) {
                    System.out.println(" 沒煙,小南先休息一會!");
                    try {
                        room.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("有煙沒?" + hasCigarette);
                if (hasCigarette) {
                    System.out.println("小南開始幹活了");
                }
            }
        }, "小南").start();

        for (int i = 0 ; i < 5 ; i++) {
            new Thread(() -> {
                synchronized (room) {
                    System.out.println("其它人開始幹活了");
                }
            },"其它人").start();
        }

        Thread.sleep(1);

        new Thread(() -> {
            synchronized (room) {
                System.out.println("有煙了");
                hasCigarette = true;
                room.notify();
            }
        }).start();
    }
}

在這裡插入圖片描述
總結:

synchronized(lock) {
		while(條件不成立) {
			lock.wait();
		}
		//幹活
}

//另一個執行緒
synchronized(lock) {
	lock.notifyAll();
}