1. 程式人生 > 其它 >Java wait和notify

Java wait和notify

wait和notify作用

waitnotify是定義在Object類中的,而且是final的。因此會被所有的Java類繼承並且無法重寫。這兩個方法要求在呼叫時所處的執行緒已經獲取了物件monitor鎖,因此對這兩個方法的呼叫需要在synchronized方法或者程式碼塊中。比如wait方法的Java Doc中也有對此的說明:

當執行緒執行了wait方法時,會釋放掉前面synchronized獲取的monitor鎖。

舉例說明

下面舉個兩個執行緒通過waitnotify進行通訊的例子:通過兩個執行緒,實現一個將int num0-1-0-1之間不斷加1和減1的功能。

Sample類

public class Sample {
    // 成員變數 持有num
    int num = 0;
    
    // 加1
    synchronized public void increase() {
        while (num != 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.num ++;
        notify();
        System.out.println(Thread.currentThread().getName() + "--" + this.num);
    }
    
    // 減1
    synchronized public void decrease() {
        while (num == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.num --;
        notify();
        System.out.println(Thread.currentThread().getName() + "--" + this.num);
    }
}

IncreaseRunnable類

public class IncreaseRunnable implements Runnable {
    Sample sample;
    public IncreaseRunnable(Sample sample) {
        this.sample = sample;
    }
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            sample.increase();
        }
    }
}

DecreaseRunnable類

public class DecreaseRunnable implements Runnable{
    Sample sample;
    public DecreaseRunnable(Sample sample) {
        this.sample = sample;
    }
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            sample.decrease();
        }
    }
}

主測試類

public class TestMain {
    public static void main(String[] args) {
        Sample sample = new Sample();
        IncreaseRunnable increaseRunnable = new IncreaseRunnable(sample);
        DecreaseRunnable decreaseRunnable = new DecreaseRunnable(sample);

        Thread t1 = new Thread(increaseRunnable);
        t1.setName("increase-thread-1");
        Thread t2 = new Thread(increaseRunnable);
        t2.setName("increase-thread-2");
        Thread t3 = new Thread(decreaseRunnable);
        t3.setName("decrease-thread-1");
        Thread t4 = new Thread(decreaseRunnable);
        t4.setName("decrease-thread-2");

        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}