wait()和notify()


從https://www.cnblogs.com/toov5/p/9837373.html 可以看到他的打印是一片一片的,這邊博客介紹怎么避免掉

使用notify 和 wait的時候 要注意 是在synchronize進行的,持有同一把鎖

1.因為涉及到對象鎖,他們必須都放在synchronized中來使用. Wait、Notify一定要在synchronized里面進行使用。

2.Wait必須暫定當前正在執行的線程,並釋放資源鎖,讓其他線程可以有機會運行

3. notify/notifyall: 喚醒因鎖池中的線程,使之運行

注意:一定要在線程同步中使用,並且是同一個鎖的資源

 

一片的原因是: cpu在調度時候 讀一直被調度上了

package com.toov5.thread;

//共享對象
class Res{
    public boolean flag = true;
    public String sex;
    public String name;
    
}

class inputThread extends Thread{
     public Res res;
     public inputThread(Res res) {
        this.res=res;
    }
    @Override
    public  void run() {
      int count=0; 
      while (true) {
          synchronized (res) {
               if (res.flag) {
              try {
                res.wait();   //此處一定要用res的wait!!!! 執行到這里就會阻塞了 下面的代碼不會執行了  釋放當前鎖對象
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            }
                if (count==0) {
                    res.name="lucy";
                    res.sex="girl";    
                }else {
                    res.name="Jack";
                    res.sex="boy";
                }
                count =(count+1)%2;
                res.flag=true;  //寫完了 標記當前線程為等待 然后走wait()了
                res.notify();  //通知讀的線程
        }
    }
    }
}

class readThread extends Thread{
    public Res res;
    public readThread(Res res) {
        this.res=res;
    }
    
    @Override
    public void run() {
        while (true) {    
        synchronized (res) {
               if(!res.flag){
                 try {
                    res.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }    
               }
               System.out.println(res.name+","+res.sex);
               //讀完了時候要 
               res.flag=false;
               res.notify();//通知寫的線程
               
            }
        }        
    }
}

public class ConmunicatThreadTest {
    //開啟兩個線程  下面的線程 主線程 還有這倆用戶線程 cpu隨機的

    public static void main(String[] args) {
        Res res = new Res();
    inputThread inputThread = new inputThread(res);
    readThread  readThread = new readThread(res);
    inputThread.start();
    readThread.start();
    
    }  
       
    
}

看下結果:

 

 

分析下: 

兩個線程 並行在執行 假設 flag為false  讀的線程會等待  cpu執行權讓給寫的線程同時鎖也會釋放掉  

                                         寫的時候 讀的線程發現為true (while(true)的情況) 等待notify() 被喚醒,被喚醒后 從wait處繼續往下執行  喚醒被等待的線程~~~

 notifyall 是喚醒所有的  小伙伴們可以自己試試哈

 注意  notify 和 wait 一定要在synchronize里面使用!!!!!並且同一個鎖對象的!  

 

wait與join 區別:

 wait需要喚醒  wait需要用在同步里面

 

wait與sleep區別

對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。

sleep()方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復運行狀態。

在調用sleep()方法的過程中,線程不會釋放對象鎖。

而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法后本線程才進入對象鎖定池准備

獲取對象鎖進入運行狀態。

  sleep不去釋放鎖 wait釋放

 

wait notify 為啥設計在object類 因為任意對象作為鎖嘛 Object是任何類的祖宗~ 所以小伙伴們都明了了吧~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM