為什么wait()和notify()屬於Object類


關於wait()暫停的是持有鎖的對象,所以想調用wait()必須為:對象.wait();

notify()喚醒的是等待鎖的對象,調用:對象.notify();

如下:

Object obj = newObject();

synchronized(obj){

    try{  

      obj.wait();

      }catch(Exception e){}

      obj.notify();

  }

注意:wait(),notify(),notifyAll()都必須使用在同步中,因為要對持有監視器(鎖)的線程操作。所以要使用在同步中,因為只有同步 才具有鎖。

為什么這些操作線程的方法要定義在object類中呢?

簡單說:因為synchronized中的這把鎖可以是任意對象,所以任意對象都可以調用wait()和notify();所以wait和notify屬於Object。

專業說:因為這些方法在操作同步線程時,都必須要標識它們操作線程的鎖,只有同一個鎖上的被等待線程,可以被同一個鎖上的notify喚醒,不可以對不同鎖中的線程進行喚醒。

也就是說,等待和喚醒必須是同一個鎖。而鎖可以是任意對象,所以可以被任意對象調用的方法是定義在object類中。

 

在jdk1.5以后,將同步synchronized替換成了Lock,將同步鎖對象換成了Condition對象,並且Condition對象可以有多個,這樣可以解決一個問題。

比如說我們在多個生產者和消費者模式中:

boolean flag = false;

public synchronized void set(String name){

  while(flag){//用while而不用if的原因,這樣每個線程在wait等待醒來后都必須再次判斷flag

    try{this.wait();}catch(Exception e){}  

    Sytem.out.printLn("生產者");

    flag = true;

    this.notifyAll();//這將喚醒所有線程(本方線程和對方線程),消耗資源

  }

}

public synchronized void out(){

  whie(!flag){

     try{this.wait();}catch(Exception e){}

    Sytem.out.printLn("消費者");

    flag = false;

    this.notifyAll();//這將喚醒所有線程(本方線程和對方線程),消耗資源

  }

}

上面的做法很消耗資源,如果把notifyAll()改成notify()的話,就會造成可能所有線程都在等待

 

所以在jdk1.5以后提供了Lock接口和Condition對象。Condition中的await(), signal().signalAll()代替Object中的wait(),notify(),notifyAll()

private Lock lock = new ReentrantLock();

private Condition condition_pro = lock.newCondition();//生產者對象

private Condition condition_con = lock.newCondition();//消費者對象

public void set(String name) throws Exception{

  lock.lock();//加鎖

  try{

    while(flag){

     contion_pro.await();

     Sytem.out.printLn("生產者");

       flag= true;

     condition_con.singal();//指定喚醒消費方

   }finally{

    lock.unlock();//解鎖    

    }  

  }

}

public void out() throws Exception{

  lock.lock();

  try{

    while(!flag){

       condition_con.await(); 

       Sytem.out.printLn("消費者");

       flag = false;

       condition_pro.signal();//指定喚醒生產方

      }finally{

      lock.unlock();  

      }

    }

}

這樣做的好處,我們可以指定喚醒某一方,減少消耗

 

Java小生店鋪:

Pc端:http://shop125970977.taobao.com/index.htm

手機端:搜索 java小生店鋪

希望店鋪的資料能幫助到你!!!

 


免責聲明!

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



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