關於wait()暫停的是持有鎖的對象,因此想調用wait()必須爲:對象.wait();java
notify()喚醒的是等待鎖的對象,調用:對象.notify();this
以下:spa
Object obj = newObject();線程
synchronized(obj){htm
try{ 對象
obj.wait();blog
}catch(Exception e){}接口
obj.notify();資源
}get
注意: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小生店鋪
但願店鋪的資料能幫助到你!!!