亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JUC中的wait與notify方法實(shí)現(xiàn)原理詳解

 更新時(shí)間:2023年03月10日 10:18:53   作者:Young丶  
這篇文章主要介紹了JUC中的wait與notify方法實(shí)現(xiàn)原理,在進(jìn)行wait()之前,就代表著需要爭(zhēng)奪Synchorized,而Synchronized代碼塊通過(guò)javap生成的字節(jié)碼中包含monitor?enter和monitor?exit兩個(gè)指令

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

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

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

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

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

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

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

_WaitSet:處于wait狀態(tài)的線(xiàn)程,會(huì)被加入到wait set;

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

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

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

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

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

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

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

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)掛起線(xiàn)程,也就是進(jìn)行wait。

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

wait,notify,notifyAll 是定義在Object類(lèi)的實(shí)例方法,用于控制線(xiàn)程狀態(tài),在線(xiàn)程協(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)有同步,所以線(xiàn)程對(duì)對(duì)象鎖的狀態(tài)是不確定的,不能調(diào)用這些方法)。

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

主要方法:

wait()

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

notify()

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

notifyAll()

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

3.wait 實(shí)戰(zhàn)

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

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ù)字線(xiàn)程先運(yùn)行
        t1.start();
    }
}
class shuzi implements Runnable{
    private Object object;
    //聲明類(lèi)的引用
    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)限的線(xiàn)程
                    try {
                        object.wait();//釋放鎖,進(jìn)入等待
                        System.out.println("數(shù)字打印類(lèi)打全打印當(dāng)前對(duì)象擁有對(duì)象鎖的線(xiàn)程"+Thread.currentThread().getName());//輸出當(dāng)前擁有鎖的線(xiàn)程名稱(chē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)限的線(xiàn)程
                try {
                    object.wait();//釋放鎖,進(jìn)入等待
                    System.out.println("字母打印類(lèi)打全打印當(dāng)前對(duì)象擁有對(duì)象鎖的線(xiàn)程"+Thread.currentThread().getName());//輸出當(dāng)前擁有鎖的線(xiàn)程名稱(chēng)
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

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

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

結(jié)果分析:

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

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

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

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

到此這篇關(guān)于JUC中的wait()與notify()方法實(shí)現(xiàn)原理詳解的文章就介紹到這了,更多相關(guān)JUC wait()與notify()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xxxController required

    解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xx

    這篇文章主要介紹了解決springboot項(xiàng)目啟動(dòng)報(bào)錯(cuò)Field xxxMapper in com...xxxContr問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring Boot 定制與優(yōu)化內(nèi)置的Tomcat容器實(shí)例詳解

    Spring Boot 定制與優(yōu)化內(nèi)置的Tomcat容器實(shí)例詳解

    本文主要記錄對(duì)內(nèi)置容器優(yōu)化和定制的方式,用于自己加深對(duì)SpringBoot理解。本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-12-12
  • 淺談redis key值內(nèi)存消耗以及性能影響

    淺談redis key值內(nèi)存消耗以及性能影響

    這篇文章主要介紹了淺談redis key值內(nèi)存消耗以及性能影響,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • java的poi技術(shù)讀取和導(dǎo)入Excel實(shí)例

    java的poi技術(shù)讀取和導(dǎo)入Excel實(shí)例

    本篇文章主要介紹了java的poi技術(shù)讀取和導(dǎo)入Excel實(shí)例,報(bào)表輸出是Java應(yīng)用開(kāi)發(fā)中經(jīng)常涉及的內(nèi)容,有需要的可以了解一下。
    2016-11-11
  • 關(guān)于HashMap源碼解讀

    關(guān)于HashMap源碼解讀

    HashMap是基于哈希表的Map接口實(shí)現(xiàn),主要用于存儲(chǔ)鍵值對(duì),它通過(guò)數(shù)組、鏈表和紅黑樹(shù)來(lái)實(shí)現(xiàn),解決了哈希沖突問(wèn)題,Java?8中,HashMap對(duì)數(shù)據(jù)結(jié)構(gòu)進(jìn)行了優(yōu)化,引入紅黑樹(shù)來(lái)提高查找效率,此外,HashMap是非線(xiàn)程安全的,適用于單線(xiàn)程環(huán)境
    2024-09-09
  • 使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能

    使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能

    這篇文章主要介紹了使用spring整合Quartz實(shí)現(xiàn)—定時(shí)器功能,不基于特定的基類(lèi)的方法,需要的朋友可以參考下
    2018-04-04
  • Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新

    Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新

    這篇文章主要介紹了Springboot使用thymeleaf動(dòng)態(tài)模板實(shí)現(xiàn)刷新,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java中解密微信加密數(shù)據(jù)工具類(lèi)

    Java中解密微信加密數(shù)據(jù)工具類(lèi)

    最近小編一直在開(kāi)發(fā)微信公眾號(hào)、小程序項(xiàng)目,微信返回給我們的數(shù)據(jù)都是加密的,我們需要使用sessionkey配合解密,才能看到我們想要的數(shù)據(jù),基于代碼怎么實(shí)現(xiàn)呢,下面小編給大家?guī)?lái)了Java中解密微信加密數(shù)據(jù)工具類(lèi)的完整代碼,一起看看吧
    2021-06-06
  • 一篇文章帶你入門(mén)java泛型

    一篇文章帶你入門(mén)java泛型

    這篇文章主要介紹了java泛型基礎(chǔ)知識(shí)及通用方法,從以下幾個(gè)方面介紹一下java的泛型: 基礎(chǔ), 泛型關(guān)鍵字, 泛型方法, 泛型類(lèi)和接口,感興趣的可以了解一下
    2021-08-08
  • 為什么阿里要慎重使用ArrayList中的subList方法

    為什么阿里要慎重使用ArrayList中的subList方法

    這篇文章主要介紹了為什么要慎重使用ArrayList中的subList方法,subList是List接口中定義的一個(gè)方法,該方法主要用于返回一個(gè)集合中的一段、可以理解為截取一個(gè)集合中的部分元素,他的返回值也是一個(gè)List。,需要的朋友可以參考下
    2019-06-06

最新評(píng)論