線程之wait/notify機制

什麼是等待/通知機制

舉個栗子:餐廳裏,廚師做好菜之後,通知等待中的服務員就是一個簡單的等待通知機制

wait:

wait方法代碼的作用是使當前執行代碼的線程進入等待,wait方法是Object類的方法,該方法用來將當前線程置入“預執行隊列當中”,並且在wait所在的代碼行處停止執行,直到接到通知或被終端爲止。在wait之前,線程必須獲得該對象的對象級別鎖,即只有在同步方法或同步塊中才能調用wait方法。wait方法執行後,當前線程會立馬釋放鎖。

notify:

notify方法在調用前,也要獲得當前線程的對象級別的鎖,即方法notify也要在同步方法或同步塊中調用。該方法用來通知那些可能等待該對象的對象鎖的其他線程,需要說明的是,在執行notify方法後,當前線程不會立馬釋放該對象鎖,呈wait狀態的線程不能立馬獲得該對象鎖,需要等到notify所在的同步塊執行完纔會釋放該對象鎖。

總結:

wait使線程停止運行,notify使通知停止的線程繼續執行。

notify一次只會隨機喚醒一個線程

看下面的代碼:

public class Service {

    public void testMothod(Object lock){
        try{
            synchronized (lock){
                System.out.println(Thread.currentThread().getName()+ " begin wait at " + System.currentTimeMillis());
                lock.wait();
                System.out.println(Thread.currentThread().getName() + " end wait at " + System.currentTimeMillis());
            }
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}
public class ThreadA extends Thread {

    private Object lock;

    public ThreadA(Object object){
        this.lock = object;
    }

    @Override
    public void run() {
        super.run();
        Service serivce = new Service();
        serivce.testMothod(lock);
    }
}
public class ThreadB extends Thread {

    private Object lock;

    public ThreadB(Object object){
        this.lock = object;
    }

    @Override
    public void run() {
        super.run();
        Service serivce = new Service();
        serivce.testMothod(lock);
    }

}
public class ThreadC extends Thread {

    private Object lock;

    public ThreadC(Object object){
        this.lock = object;
    }

    @Override
    public void run() {
        super.run();
        Service serivce = new Service();
        serivce.testMothod(lock);
    }

}
public class NotifyOne extends Thread {

    private Object lock;

    public NotifyOne(Object object){
        this.lock = object;
    }

    @Override
    public void run() {
        super.run();
        synchronized (lock){
            lock.notify();
        }
    }
}
public class Test {

    public static void main(String[] args) {

        try{
            Object object = new Object();
            ThreadA threadA = new ThreadA(object);
            ThreadB threadB = new ThreadB(object);
            ThreadC threadC = new ThreadC(object);

            threadA.setName("A");
            threadB.setName("B");
            threadC.setName("C");

            threadA.start();
            threadB.start();
            threadC.start();

            Thread.sleep(1000);
            NotifyOne notifyOne = new NotifyOne(object);
            notifyOne.start();
        } catch (InterruptedException e){
            e.printStackTrace();
        }
    }
}

運行結果:

A begin wait at 1563079593045
B begin wait at 1563079593045
C begin wait at 1563079593045
A end wait at 1563079594044

可以看到 notify方法只喚醒了A線程,那麼喚醒所有線程的方法就是notifyAll嘍

修改NotifyOne類中的notify方法爲notifyAll

public class NotifyOne extends Thread {

    private Object lock;

    public NotifyOne(Object object){
        this.lock = object;
    }

    @Override
    public void run() {
        super.run();
        synchronized (lock){
            lock.notifyAll();
        }
    }
}

運行結果:

A begin wait at 1563079801021
C begin wait at 1563079801022
B begin wait at 1563079801022
B end wait at 1563079802012
C end wait at 1563079802012
A end wait at 1563079802012

Process finished with exit code 0

可以看到,A B C三個線程都被喚醒了

wait(long)方法介紹

該方法是等待參數值的時間內如果沒有線程對鎖進行喚醒,如果超過這個時間,則自動喚醒。

 

That's ALL !!!!!!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章