最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

java的Object里wait()實(shí)現(xiàn)原理講解

 更新時(shí)間:2021年09月27日 11:00:28   作者:ZytheMoon  
這篇文章主要介紹了java的Object里wait()實(shí)現(xiàn)原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Object中的wait()實(shí)現(xiàn)原理

在進(jìn)行wait()之前,就代表著需要爭(zhēng)奪Synchorized,而Synchronized代碼塊通過(guò)javap生成的字節(jié)碼中包含monitorenter和monitorexit兩個(gè)指令。

當(dāng)在進(jìn)加鎖的時(shí)候會(huì)執(zhí)行monitorenter指令,執(zhí)行該指令可以獲取對(duì)象的monitor。同時(shí)在執(zhí)行Lock.wait()的時(shí)候也必須持有monitor對(duì)象。

在多核環(huán)境下,多個(gè)線程有可能同時(shí)執(zhí)行monitorenter指令,并獲取lock對(duì)象關(guān)聯(lián)的monitor,但只有一個(gè)線程可以和monitor建立關(guān)聯(lián),這個(gè)線程執(zhí)行到wait方法時(shí),wait方法會(huì)將當(dāng)前線程放入wait set,使其進(jìn)行等待直到被喚醒,并放棄lock對(duì)象上的所有同步聲明,意味著該線程釋放了鎖,其他線程可以重新執(zhí)行加鎖操作,notify方法會(huì)選擇wait set中任意一個(gè)線程進(jìn)行喚醒,notifyAll方法會(huì)喚醒monitor的wait set中所有線程。執(zhí)行完notify方法并不會(huì)立馬喚醒等待線程。那么wait具體是怎么實(shí)現(xiàn)的呢?

首先在HotSpot虛擬機(jī)中,monitor采用ObjectMonitor實(shí)現(xiàn),每個(gè)線程都具有兩個(gè)隊(duì)列,分別為free和used,用來(lái)存放ObjectMonitor。如果當(dāng)前free列表為空,線程將向全局global list請(qǐng)求分配ObjectMonitor。

ObjectMonitor對(duì)象中有兩個(gè)隊(duì)列,都用來(lái)保存ObjectWaiter對(duì)象,分別是_WaitSet 和 _EntrySet。_owner用來(lái)指向獲得ObjectMonitor對(duì)象的線程

ObjectWaiter對(duì)象是雙向鏈表結(jié)構(gòu),保存了_thread(當(dāng)前線程)以及當(dāng)前的狀態(tài)TState等數(shù)據(jù), 每個(gè)等待鎖的線程都會(huì)被封裝成ObjectWaiter對(duì)象。

  • _WaitSet:處于wait狀態(tài)的線程,會(huì)被加入到wait set;
  • _EntrySett:處于等待鎖block狀態(tài)的線程,會(huì)被加入到entry set;

wait方法實(shí)現(xiàn)

lock.wait()方法最終通過(guò)ObjectMonitor的 wait(jlong millis, bool interruptable, TRAPS)實(shí)現(xiàn)

1、將當(dāng)前線程封裝成ObjectWaiter對(duì)象node

2、通過(guò)ObjectMonitor::AddWaiter方法將node添加到_WaitSet列表中

3、通過(guò)ObjectMonitor::exit方法釋放當(dāng)前的ObjectMonitor對(duì)象,這樣其它競(jìng)爭(zhēng)線程就可以獲取該ObjectMonitor對(duì)象

4、最終底層的park方法會(huì)掛起線程

ObjectSynchorizer::wait方法通過(guò)Object對(duì)象找到ObjectMonitor對(duì)象來(lái)調(diào)用方法 ObjectMonitor::wait(),通過(guò)調(diào)用ObjectMonitor::AddWaiter()可以把新建的ObjectWaiter對(duì)象,放入到_WaitSet隊(duì)列的末尾,然后在ObjectMonitor::exit釋放鎖,接著通過(guò)執(zhí)行thread_ParkEvent->park來(lái)掛起線程,也就是進(jìn)行wait。

Object對(duì)象中的wait,notify,notifyAll的理解

wait,notify,notifyAll 是定義在Object類的實(shí)例方法,用于控制線程狀態(tài),在線程協(xié)作時(shí),大家都會(huì)用到notify()或者notifyAll()方法,其中wait與notify是java同步機(jī)制中重要的組成部分,需要結(jié)合與synchronized關(guān)鍵字才能使用,在調(diào)用一個(gè)Object的wait與notify/notifyAll的時(shí)候,必須保證調(diào)用代碼對(duì)該Object是同步的,也就是說(shuō)必須在作用等同于synchronized(object){......}的內(nèi)部才能夠去調(diào)用obj的wait與notify/notifyAll三個(gè)方法,否則就會(huì)報(bào)錯(cuò):java.lang.IllegalMonitorStateException:current thread not owner(意思是因?yàn)闆](méi)有同步,所以線程對(duì)對(duì)象鎖的狀態(tài)是不確定的,不能調(diào)用這些方法)。

wait的目的就在于暴露出對(duì)象鎖,所以需要保證在lock的同步代碼中調(diào)用lock.wait()方法,讓其他線程可以通過(guò)對(duì)象的notify叫醒等待在該對(duì)象的等該池里的線程。同樣notify也會(huì)釋放對(duì)象鎖,在調(diào)用之前必須獲得對(duì)象的鎖,不然也會(huì)報(bào)異常。所以,在線程自動(dòng)釋放其占有的對(duì)象鎖后,不會(huì)去申請(qǐng)對(duì)象鎖,只有當(dāng)線程被喚醒的時(shí)候或者達(dá)到最大的睡眠時(shí)間,它才再次爭(zhēng)取對(duì)象鎖的權(quán)利

主要方法:

(1).wait()

等待對(duì)象的同步鎖,需要獲得該對(duì)象的同步鎖才可以調(diào)用這個(gè)方法,否則編譯可以通過(guò),但運(yùn)行時(shí)會(huì)收到一個(gè)異常:IllegalMonitorStateException。調(diào)用任意對(duì)象的 wait() 方法導(dǎo)致該線程阻塞,該線程不可繼續(xù)執(zhí)行,并且該對(duì)象上的鎖被釋放。

(2).notify()

喚醒在等待該對(duì)象同步鎖的線程(只喚醒一個(gè),如果有多個(gè)在等待),注意的是在調(diào)用此方法的時(shí)候,并不能確切的喚醒某一個(gè)等待狀態(tài)的線程,而是由JVM確定喚醒哪個(gè)線程,而且不是按優(yōu)先級(jí)。調(diào)用任意對(duì)象的notify()方法則導(dǎo)致因調(diào)用該對(duì)象的 wait()方法而阻塞的線程中隨機(jī)選擇的一個(gè)解除阻塞(但要等到獲得鎖后才真正可執(zhí)行)。

(3).notifyAll()

喚醒所有等待的線程,注意喚醒的是notify之前wait的線程,對(duì)于notify之后的wait線程是沒(méi)有效果的。

通過(guò)一個(gè)實(shí)例來(lái)看一下實(shí)際的效果,開(kāi)啟兩個(gè)線和,一個(gè)線程 打印1到52的數(shù)字,一個(gè)打印A到Z的字母,要求,打印兩個(gè)數(shù),打印一個(gè)字母,這樣交替順序打印,代碼如下:

/**
 * create by spy on 2018/6/4
 */
public class ShuZiZiMuThread {
    public static void main(String[] args) {
        Object object = new Object();
        shuzi shuzi = new shuzi(object);
        zimu zimu = new zimu(object);
        Thread t = new Thread(shuzi);
        t.setName("shuzi");
        Thread t1 = new Thread(zimu);
        t1.setName("zimu");
        t.start();//數(shù)字線程先運(yùn)行
        t1.start();
    }
}
class shuzi implements Runnable{
    private Object object;
    //聲明類的引用
    public shuzi(Object object) {
        this.object = object;
    }
    public void run() {
        synchronized (object) {//上鎖
            for(int i=1;i<53;i++){
                System.out.print(i+",");
                if(i%2==0){
                    object.notifyAll();//喚醒其它爭(zhēng)奪權(quán)限的線程
                    try {
                        object.wait();//釋放鎖,進(jìn)入等待
                        System.out.println("數(shù)字打印類打全打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程"+Thread.currentThread().getName());//輸出當(dāng)前擁有鎖的線程名稱
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
class zimu implements Runnable{
    private Object object;
    public zimu(Object object) {
        this.object = object;
    }
    public void run() {
        synchronized (object) {
            for(int j=65;j<91;j++){
                char c = (char)j;
                System.out.print(c);
                object.notifyAll();//喚醒其它爭(zhēng)奪權(quán)限的線程
                try {
                    object.wait();//釋放鎖,進(jìn)入等待
                    System.out.println("字母打印類打全打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程"+Thread.currentThread().getName());//輸出當(dāng)前擁有鎖的線程名稱
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

實(shí)際運(yùn)行的結(jié)果 :

1,2,A數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
3,4,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
B數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
5,6,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
C數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
7,8,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
D數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
9,10,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
E數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
11,12,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
F數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
13,14,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
G數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
15,16,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
H數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
17,18,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
I數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
19,20,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
J數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
21,22,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
K數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
23,24,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
L數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
25,26,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
M數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
27,28,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
N數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
29,30,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
O數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
31,32,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
P數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
33,34,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
Q數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
35,36,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
R數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
37,38,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
S數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
39,40,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
T數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
41,42,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
U數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
43,44,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
V數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
45,46,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
W數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
47,48,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
X數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
49,50,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
Y數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi
51,52,字母打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程zimu
Z數(shù)字打印類打印當(dāng)前對(duì)象擁有對(duì)象鎖的線程shuzi

結(jié)果分析:

通過(guò)結(jié)果可以看出:

在字母打一打印類里 調(diào)用完

object.notifyAll();//喚醒其它爭(zhēng)奪權(quán)限的線程
object.wait();//釋放鎖,進(jìn)入等待后,擁有對(duì)象鎖的線程是shuzi在數(shù)字打印類里 調(diào)用完
object.notifyAll();//喚醒其它爭(zhēng)奪權(quán)限的線程
object.wait();//釋放鎖,進(jìn)入等待后,擁有對(duì)象鎖的線程是zimu

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringSecurity+Redis認(rèn)證過(guò)程小結(jié)

    SpringSecurity+Redis認(rèn)證過(guò)程小結(jié)

    這篇文章主要介紹了SpringSecurity+Redis認(rèn)證過(guò)程小結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-01-01
  • 淺析Java語(yǔ)言中狀態(tài)模式的優(yōu)點(diǎn)

    淺析Java語(yǔ)言中狀態(tài)模式的優(yōu)點(diǎn)

    狀態(tài)模式允許對(duì)象在內(nèi)部狀態(tài)改變時(shí)改變它的行為,對(duì)象看起來(lái)好像修改了它的類。這個(gè)模式將狀態(tài)封裝成獨(dú)立的類,并將動(dòng)作委托到 代表當(dāng)前狀態(tài)的對(duì)象,我們知道行為會(huì)隨著內(nèi)部狀態(tài)而改變
    2023-02-02
  • Java實(shí)現(xiàn)簡(jiǎn)易學(xué)籍管理系統(tǒng)

    Java實(shí)現(xiàn)簡(jiǎn)易學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡(jiǎn)易學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • springcloud初體驗(yàn)(真香)

    springcloud初體驗(yàn)(真香)

    這篇文章主要介紹了springcloud初體驗(yàn)(真香),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例

    Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例

    本文主要介紹了Spring?Cloud?Gateway編碼實(shí)現(xiàn)任意地址跳轉(zhuǎn)的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java的線程與進(jìn)程以及線程的四種創(chuàng)建方式

    Java的線程與進(jìn)程以及線程的四種創(chuàng)建方式

    這篇文章主要為大家詳細(xì)介紹了Java的線程與進(jìn)程以及線程的四種創(chuàng)建方式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-03-03
  • Java虛擬機(jī)精選面試題20道

    Java虛擬機(jī)精選面試題20道

    現(xiàn)在面試Java開(kāi)發(fā)時(shí),基本都會(huì)問(wèn)到Java虛擬機(jī)的知識(shí),根據(jù)職位不同問(wèn)的內(nèi)容深淺又有所區(qū)別。本文整理了10道面試中常問(wèn)的Java虛擬機(jī)面試題,希望對(duì)正在面試的同學(xué)有所幫助
    2021-06-06
  • Java基礎(chǔ)泛型詳情

    Java基礎(chǔ)泛型詳情

    這篇文章主要介紹了Java基礎(chǔ)泛型詳情,泛型是JDK5中引入的特性,它提供了編譯時(shí)類型安全檢測(cè)機(jī)制,該機(jī)制允許在編譯時(shí)檢測(cè)到非法的類型,下面文章的詳細(xì)介紹,需要的朋友可以參考一下
    2022-04-04
  • 實(shí)體類使用@Builder,導(dǎo)致@ConfigurationProperties注入屬性失敗問(wèn)題

    實(shí)體類使用@Builder,導(dǎo)致@ConfigurationProperties注入屬性失敗問(wèn)題

    這篇文章主要介紹了實(shí)體類使用@Builder,導(dǎo)致@ConfigurationProperties注入屬性失敗問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java 中的HashMap詳解和使用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java 中的HashMap詳解和使用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java 中的HashMap詳解和使用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下
    2017-05-05

最新評(píng)論

许昌市| 海原县| 浮梁县| 平罗县| 龙岩市| 庆元县| 龙州县| 佛山市| 汶上县| 濮阳市| 吉林市| 松江区| 盐城市| 松原市| 镇坪县| 海晏县| 宁晋县| 南通市| 泸西县| 连城县| 凤庆县| 上杭县| 萨迦县| 铁岭市| 旬阳县| 和林格尔县| 吉首市| 石家庄市| 浦县| 屯留县| 乐平市| 阳西县| 大方县| 华宁县| 湘西| 沁阳市| 阿坝县| 道真| 乌兰察布市| 娄底市| 金门县|