用实例揭示notify()和notifyAll()的本质区别
用實(shí)例揭示notify()和notifyAll()的本質(zhì)區(qū)別 收藏
notify()和notifyAll()都是Object對(duì)象用于通知處在等待該對(duì)象的線程的方法。兩者的最大區(qū)別在于:
notifyAll使所有原來在該對(duì)象上等待被notify的線程統(tǒng)統(tǒng)退出wait的狀態(tài),變成等待該對(duì)象上的鎖,一旦該對(duì)象被解鎖,他們就會(huì)去競(jìng)爭(zhēng)。
notify則文明得多他只是選擇一個(gè)wait狀態(tài)線程進(jìn)行通知,并使它獲得該對(duì)象上的鎖,但不驚動(dòng)其他同樣在等待被該對(duì)象notify的線程們,當(dāng)?shù)谝粋€(gè)線程運(yùn)行完畢以后釋放對(duì)象上的鎖此時(shí)如果該對(duì)象沒有再次使用notify語句,則即便該對(duì)象已經(jīng)空閑,其他wait狀態(tài)等待的線程由于沒有得到該對(duì)象的通知,繼續(xù)處在wait狀態(tài),直到這個(gè)對(duì)象發(fā)出一個(gè)notify或notifyAll,它們等待的是被notify或notifyAll,而不是鎖。
下面是一個(gè)很好的例子:
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秒鐘才能新產(chǎn)生一個(gè)Widget,這決定了一定要用notify而不是notifyAll
??????????????? //因?yàn)樯厦鎯尚写a不是同步的,如果用notifyAll則所有線程都企圖沖出wait狀態(tài)
??????????????? //第一個(gè)線程得到了鎖,并取走了Widget(這個(gè)過程的時(shí)間小于5秒,新的Widget還沒有生成)
??????????????? //并且解開了鎖,然后第二個(gè)線程獲得鎖(因?yàn)橛昧薾otifyAll其他線程不再等待notify語句
??????????????? //,而是等待finishedWidgets上的鎖,一旦鎖放開了,他們就會(huì)競(jìng)爭(zhēng)運(yùn)行),運(yùn)行
??????????????? //finishedWidgets.remove(0),但是由于finishedWidgets現(xiàn)在還是空的,
??????????????? //于是產(chǎn)生異常
??????????????? //***********這就是為什么下面的那一句不能用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博客,轉(zhuǎn)載請(qǐng)標(biāo)明出處:http://blog.csdn.net/SuperMiner/archive/2007/04/22/1574615.aspx
轉(zhuǎn)載于:https://www.cnblogs.com/w-wfy/p/5893270.html
總結(jié)
以上是生活随笔為你收集整理的用实例揭示notify()和notifyAll()的本质区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 明星qq网名大全
- 下一篇: GitLab安装说明