日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Object类中的两个方法——wait和notify使用总结

發(fā)布時間:2024/2/28 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Object类中的两个方法——wait和notify使用总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.



?? ?Object類中的wait 、和 notify方法是用來處理線程的方法,既然定義在Object類中,兩個方法的重要程度可見一斑:

兩個方法的使用上都很復(fù)雜:通過閱讀API獲得更多對方法的理解:

The current thread must own this object'smonitor. The thread releases ownership of this monitor and waits until anotherthread notifies threads waiting on this object's monitor to wake up eitherthrough a call to thenotify method or the notifyAll method. The thread then waits until it can re-obtain ownership ofthe monitor and resumes execution

?

?

“當(dāng)前的線程必須要獲得對象的鎖!”

實(shí)現(xiàn)這個條件的做法就是wait 方法一定要定義在synchronized方法中或者synchronized代碼塊中;

線程必須要兩次獲得鎖才能完全的執(zhí)行synchronized中的所有內(nèi)容;

當(dāng)?shù)谝淮握{(diào)用到達(dá)wait方法時,The thread realeases ownership of this monitor and waituntil another thread notifies threads waiting on this …

線程會暫時釋放鎖的擁有權(quán),等待其他線程的notify方法或者notifyAll方法喚醒該線程,繼續(xù)執(zhí)行代碼!

?

?

?

30.

下面一個程序要求定義兩個線程類,一個實(shí)現(xiàn)將目標(biāo)加一,一個實(shí)現(xiàn)將目標(biāo)減一,目標(biāo)初始值為零,要求加一減一交替進(jìn)行;

顯然的單純調(diào)用synchronized是無法滿足條件的,需要使用wait,和notify方法;

?

package thread;

?

publicclass ThreadTest

{

?

?? publicstaticvoid main(String[] args)

?? {

????? ThreadDemo2 demo = new ThreadDemo2();

????? ThreadIncrease test1 = new ThreadIncrease(demo);

????? ThreadDecrease test2 = new ThreadDecrease(demo);

????? test1.start();

????? test2.start();

?? }

}

class ThreadDemo2

{

?? privateintnum = 0;

?? publicsynchronizedvoid Increase()

?? {

????? /*

????? ?* 下面的代碼是核心代碼

????? ?* 什么時候要讓線程等待,當(dāng)然是不符合條件的時候

????? ?* 目的是想讓num = 0 的時候才執(zhí)行加一的操作,當(dāng)num不等于零的時候會執(zhí)行wait等待通知

????? ?* 當(dāng)通知num已經(jīng)變?yōu)?/span>0時,wait結(jié)束,執(zhí)行下面語句num++;

????? ?* 然后執(zhí)行notify方法!

????? ?* 當(dāng)然的一說Java中的synchronized總是伴隨著waitnotify方法共同的存在;

????? ?*/

?????

????? if(num != 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num ++;

????? System.out.println(num);

????? notify();

????? }

??

?? publicsynchronizedvoid decrease()

?? {

?????

????? if(num == 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num --;

????? System.out.println(num);

?????

????? notify();

????? }

?????

??

}

class ThreadIncreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadIncrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?? }

?? @Override

?? publicvoid run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

????? demo.Increase();

????? }

?? }

??

}

class ThreadDecreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadDecrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?????

?? }

?? @Override

?? publicvoid run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

????? demo.decrease();

????? }

?? }

}

?

?

?

31.

可惜的是上面的代碼仍然有著致命的弱點(diǎn),線程并不僅僅有兩個,而且是兩個相對的線程!

致命的弱點(diǎn)在于: 當(dāng)線程在wait的時候它并不知道其他的線程到底做了什么!

現(xiàn)在我們將增加一個Increase線程類,和一個Decrease線程類

,并且調(diào)用它們的start方法運(yùn)行后,你將看到這樣的結(jié)果:

我們足以看到代碼的脆弱性,為什么會出現(xiàn)這種情況,更糟糕的是結(jié)果是隨機(jī)的!上面已經(jīng)說得很清楚了:當(dāng)線程在wait的時候,它不知道其他的線程正在做什么,

所以需要將代碼變得更加健壯:

我們舉一個為什么會出現(xiàn)這種情況的原因之一:

我們假設(shè)線程1、2調(diào)用增加方法,線程3、4調(diào)用減少方法

假設(shè)線程3 先訪問了減少方法,因?yàn)榇藭rnum的值為0,所以wait,并且交出ownership,假設(shè)線程4又訪問了減少方法,同樣的wait,并且交出所有權(quán),再假設(shè)線程1訪問了增加方法,將num的值變?yōu)?,并且調(diào)用notify方法,假設(shè)notify了線程3,線程3將num的值變?yōu)?;并且notify,如果此時notify了線程4,那么悲劇就會發(fā)生了,線程4醒來后,會繼續(xù)將num減一,變?yōu)?1,一步錯,后面就全錯了;

缺點(diǎn)就在于notify的隨機(jī)性,所以在某個wait方法被喚醒時,增加判斷條件,如果不符合條件,繼續(xù)wait,顯然 while循環(huán)是最合適的

!

全部的變化只需要將 if 改為 while!!

由于num是成員變量被線程共享,每當(dāng)wait被喚醒,都會判斷一次;

package thread;

?

publicclass ThreadTest

{

?

?? publicstaticvoid main(String[] args)

?? {

????? ThreadDemo2 demo = new ThreadDemo2();

????? ThreadIncrease test1 = new ThreadIncrease(demo);

????? ThreadDecrease test2 = new ThreadDecrease(demo);

????? ThreadIncrease test3 = new ThreadIncrease(demo);

????? ThreadDecrease test4 = new ThreadDecrease(demo);

????? test1.start();

????? test2.start();

????? test3.start();

????? test4.start();

?? }

}

class ThreadDemo2

{

?? privateintnum = 0;

?? publicsynchronizedvoid Increase()

?? {

????? /*

????? ?* 下面的代碼是核心代碼

????? ?* 什么時候要讓線程等待,當(dāng)然是不符合條件的時候

????? ?* 目的是想讓num = 0 的時候才執(zhí)行加一的操作,當(dāng)num不等于零的時候會執(zhí)行wait等待通知

????? ?* 當(dāng)通知num已經(jīng)變?yōu)?/span>0時,wait結(jié)束,執(zhí)行下面語句num++;

????? ?* 然后執(zhí)行notify方法!

????? ?* 當(dāng)然的一說Java中的synchronized總是伴隨著waitnotify方法共同的存在;

????? ?*/

?????

?? ?? while(num != 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num ++;

????? System.out.println(num);

????? notify();

????? }

??

?? publicsynchronizedvoid decrease()

?? {

?????

????? while(num == 0)

????? {

??????? try

??????? {

?????????? wait();

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

????? }

????? num --;

????? System.out.println(num);

?????

????? notify();

????? }

?????

??

}

class ThreadIncreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadIncrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?? }

?? @Override

?? publicvoid run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

??????? try

??????? {

?????????? Thread.sleep((long)(Math.random()*1000));

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

??????? demo.Increase();

????? }

?? }

??

}

class ThreadDecreaseextends Thread

{

?? private ThreadDemo2demo;

?? public ThreadDecrease(ThreadDemo2 demo)

?? {

????? this.demo = demo;

?????

?? }

?? @Override

?? publicvoid run()

?? {

????? for(int i = 0 ; i < 15; i ++)

????? {

??????? try

??????? {

?????????? Thread.sleep((long)(Math.random()*1000));

??????? }

??????? catch (InterruptedException e)

??????? {

?????????? // TODO Auto-generatedcatch block

?????????? e.printStackTrace();

??????? }

??????? demo.decrease();

????? }

?? }

}

總結(jié)

以上是生活随笔為你收集整理的Object类中的两个方法——wait和notify使用总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。