用实例揭示notify()和notifyAll()的本质区别
用實例揭示notify()和notifyAll()的本質區別 收藏
notify()和notifyAll()都是Object對象用于通知處在等待該對象的線程的方法。兩者的最大區別在于:
notifyAll使所有原來在該對象上等待被notify的線程統統退出wait的狀態,變成等待該對象上的鎖,一旦該對象被解鎖,他們就會去競爭。
notify則文明得多他只是選擇一個wait狀態線程進行通知,并使它獲得該對象上的鎖,但不驚動其他同樣在等待被該對象notify的線程們,當第一個線程運行完畢以后釋放對象上的鎖此時如果該對象沒有再次使用notify語句,則即便該對象已經空閑,其他wait狀態等待的線程由于沒有得到該對象的通知,繼續處在wait狀態,直到這個對象發出一個notify或notifyAll,它們等待的是被notify或notifyAll,而不是鎖。
下面是一個很好的例子:
import java.util.*;
class Widget...{}
class WidgetMaker extends Thread...{
??? List<Widget> finishedWidgets=new ArrayList<Widget>();
??? public void run()...{
??????? try...{
??????????? while(true)...{
??????????????? Thread.sleep(5000);//act busy
??????????????? Widget w=new Widget();
??????????????? //也就是說需要5秒鐘才能新產生一個Widget,這決定了一定要用notify而不是notifyAll
??????????????? //因為上面兩行代碼不是同步的,如果用notifyAll則所有線程都企圖沖出wait狀態
??????????????? //第一個線程得到了鎖,并取走了Widget(這個過程的時間小于5秒,新的Widget還沒有生成)
??????????????? //并且解開了鎖,然后第二個線程獲得鎖(因為用了notifyAll其他線程不再等待notify語句
??????????????? //,而是等待finishedWidgets上的鎖,一旦鎖放開了,他們就會競爭運行),運行
??????????????? //finishedWidgets.remove(0),但是由于finishedWidgets現在還是空的,
??????????????? //于是產生異常
??????????????? //***********這就是為什么下面的那一句不能用notifyAll而是要用notify
????????????????????????????????
??????????????? synchronized(finishedWidgets)...{
??????????????????? finishedWidgets.add(w);
??????????????????? finishedWidgets.notify(); //這里只能是notify而不能是notifyAll
??????????????? }
??????????? }
??????? }
??????? catch(InterruptedException e)...{}
??? }
????
??? public Widget waitForWidget()...{
??????? synchronized(finishedWidgets)...{
??????????? if(finishedWidgets.size()==0)...{
??????????????? try...{
??????????????????? finishedWidgets.wait();
??????????????? }
??????????????? catch(InterruptedException e)
??????????????? ...{}
??????????? }
??????????? return finishedWidgets.remove(0);
??????? }
??? }
}
public class WidgetUser extends Thread...{
??? private WidgetMaker maker;
??? public WidgetUser(String name,WidgetMaker maker)...{
??????? super(name);
??????? this.maker=maker;
??? }
??? public void run()...{
??????? Widget w=maker.waitForWidget();
??????? System.out.println(getName()+"got a widget");
??? }
???
??? public static void main(String[] args) ...{
??????? WidgetMaker maker=new WidgetMaker();
??????? maker.start();
??????? new WidgetUser("Lenny",maker).start();
??????? new WidgetUser("Moe",maker).start();
??????? new WidgetUser("Curly",maker).start();
??? }
}
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/SuperMiner/archive/2007/04/22/1574615.aspx
轉載于:https://www.cnblogs.com/w-wfy/p/5893270.html
總結
以上是生活随笔為你收集整理的用实例揭示notify()和notifyAll()的本质区别的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 明星qq网名大全
- 下一篇: 知我心者下一句是什么呢?