Java-0027-Synchronized同步-wait()和notify()

2016.8.5

寫這么個(gè)例子:
有一個(gè)盒子,里面只能放一個(gè)數(shù)字,
盒子空時(shí)生產(chǎn)者才能放入數(shù)字,
盒子滿時(shí)消費(fèi)者才能取出數(shù)字。

盒子

class Box {
    public int boxValue=0;
}

生產(chǎn)者

class Producer extends Thread{
    private Box box;
    public Producer(Box box){
        this.box=box;
    }
    public void run(){
        for(int i=1;i<=10;i++){
            synchronized(box){
                while(box.boxValue!=0){
                    System.out.println("生產(chǎn)者:滿了");
                    try {
                        box.wait();//線程休眠,等待喚醒,并釋放box對(duì)象鎖
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                box.boxValue=i;
                System.out.println("生產(chǎn)者放入了數(shù)字:"+i);
                box.notify();//隨機(jī)喚醒一個(gè)正在等待box的線程
            }
        }
    }
}

消費(fèi)者

class Consumer extends Thread{
    private Box box;
    public Consumer(Box box){
        this.box=box;
    }
    public void run(){
        for(int i=1;i<=5;i++){
            synchronized(box){
                while(box.boxValue==0){
                    System.out.println("消費(fèi)者:空了");
                    try {
                        box.wait();//線程休眠,等待喚醒,并釋放box對(duì)象鎖
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                System.out.println("消費(fèi)者取出了數(shù)字:"+box.boxValue);
                box.boxValue=0;
                box.notify();//隨機(jī)喚醒一個(gè)正在等待box的線程
            }
        }
    }
}

運(yùn)行

    public static void main(String[] args){
        Box box = new Box();
        Thread producer = new Producer(box);
        Thread consumer = new Consumer(box);
        producer.start();
        consumer.start();   
    }

結(jié)果

搜狗截圖20160805142606.png

總結(jié)

  1. wait()和notify()只能寫在synchronized同步方法或同步塊中。
  2. wait(),線程休眠,等待喚醒,并釋放對(duì)象鎖(monitor)
  3. notify(),隨機(jī)喚醒一個(gè)正在等待對(duì)象鎖的線程
  4. notifyAll(),喚醒所有正在等待對(duì)象鎖的線程
  5. 若沒有正在等待對(duì)象鎖的線程,則notify()和notifyAll()不起作用
  6. 一個(gè)線程被喚醒不代表立即獲取了對(duì)象的monitor,只有等調(diào)用完notify()或者notifyAll()并退出synchronized塊,釋放對(duì)象鎖后,其余線程才可獲得鎖執(zhí)行。
  7. 至于哪個(gè)線程接下來能夠獲取到對(duì)象的monitor就具體依賴于操作系統(tǒng)的調(diào)度了。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.解決信號(hào)量丟失和假喚醒 public class MyWaitNotify3{ MonitorObject m...
    Q羅閱讀 993評(píng)論 0 1
  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,297評(píng)論 0 14
  • 一、進(jìn)程和線程 進(jìn)程 進(jìn)程就是一個(gè)執(zhí)行中的程序?qū)嵗?,每個(gè)進(jìn)程都有自己獨(dú)立的一塊內(nèi)存空間,一個(gè)進(jìn)程中可以有多個(gè)線程。...
    阿敏其人閱讀 2,688評(píng)論 0 13
  • 九種基本類型及封裝類 switch語句后的控制表達(dá)式只能是short、char、int、long整數(shù)類型和枚舉類型...
    zhazhaxin閱讀 3,793評(píng)論 14 85
  • 相關(guān)概念 面向?qū)ο蟮娜齻€(gè)特征 封裝,繼承,多態(tài).這個(gè)應(yīng)該是人人皆知.有時(shí)候也會(huì)加上抽象. 多態(tài)的好處 允許不同類對(duì)...
    東經(jīng)315度閱讀 2,191評(píng)論 0 8

友情鏈接更多精彩內(nèi)容