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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

对jvm 同步锁的理解

發(fā)布時間:2023/12/19 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 对jvm 同步锁的理解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

sychronized是jvm中對線程同步的主要方法和機制。

Thread.sleep是讓線程丟掉cpu分配資源(讓調(diào)度器在某時間內(nèi)不再調(diào)度該線程)。

一個對象的鎖只能同時被一個線程所持有。

對于每一個線程都是兩個ObjectMinor list,一個是freelist,一個是usedlist;usedlist是該線程占有那些對象的鎖,一個線程可以占有多個對象的鎖。

jvm ObjectMinor源代碼:

ObjectMonitor() {_header = NULL;//markOop對象頭_count = 0;_waiters = 0,//等待線程數(shù)_recursions = 0;//重入次數(shù)_object = NULL;//監(jiān)視器鎖寄生的對象。鎖不是平白出現(xiàn)的,而是寄托存儲于對象中。_owner = NULL;//指向獲得ObjectMonitor對象的線程或基礎(chǔ)鎖_WaitSet = NULL;//處于wait狀態(tài)的線程,會被加入到wait set;_WaitSetLock = 0 ;_Responsible = NULL ;_succ = NULL ;_cxq = NULL ;FreeNext = NULL ;_EntryList = NULL ;//處于等待鎖block狀態(tài)的線程,會被加入到entry set;_SpinFreq = 0 ;_SpinClock = 0 ;OwnerIsThread = 0 ;// _owner is (Thread *) vs SP/BasicLock_previous_owner_tid = 0;// 監(jiān)視器前一個擁有者線程的ID}

object notify() 隨意獲取(之前調(diào)用wait而阻塞的線程)一個線程喚醒去執(zhí)行,但是去執(zhí)行不一定是直接獲取這個對象的鎖,或者執(zhí)行這個對象中方法,只是喚醒而已。但是注意:去執(zhí)行object.notify的線程必須是獲取該對象object的鎖的線程,否則會爆出IllegalMonitorStateException。因為只有持有該對象的鎖,該線程中的minor usedlist才有該對象的objectminor,才有能力獲取該objectminor中的_WaitSet 等待隊列。

對于ObjectMinor中EntrySet存放的阻塞block隊列,我們是沒有辦法直接喚醒的.

每個object都包含markOop。如下圖所示:

class oopDesc {friend class VMStructs;private:volatile markOop _mark;//markOop:Mark Word標(biāo)記字段union _metadata {Klass* _klass;//對象類型元數(shù)據(jù)的指針narrowKlass _compressed_klass;} _metadata;// Fast access to barrier set. Must be initialized.static BarrierSet* _bs;public:markOop mark() const { return _mark; }markOop* mark_addr() const { return (markOop*) &_mark; }void set_mark(volatile markOop m) { _mark = m; }void release_set_mark(markOop m);markOop cas_set_mark(markOop new_mark, markOop old_mark);// Used only to re-initialize the mark word (e.g., of promoted// objects during a GC) -- requires a valid klass pointervoid init_mark();Klass* klass() const;Klass* klass_or_null() const volatile;Klass** klass_addr();narrowKlass* compressed_klass_addr();} oopDesc --繼承--> markOopDesc --方法monitor()--> ObjectMonitor-->enter、exit 獲取、釋放鎖

markOopDesc類

openjdk\hotspot\src\share\vm\oops\markOop.hpp下markOopDesc繼承自oopDesc,并拓展了自己的方法monitor(),如下圖

ObjectMonitor* monitor() const {assert(has_monitor(), "check");// Use xor instead of &~ to provide one extra tag-bit check.return (ObjectMonitor*) (value() ^ monitor_value);}

說說EntrySet和waitSet隊列:


(1)所有期待獲得鎖的線程,在鎖已經(jīng)被其它線程擁有的時候,這些期待獲得鎖的線程就進入了Object Lock的entry set區(qū)域。

(2)所有曾經(jīng)獲得過鎖,但是由于其它必要條件不滿足而需要wait的時候,線程就進入了Object Lock的wait set區(qū)域?。

(3)在wait set區(qū)域的線程獲得Notify/notifyAll通知的時候,隨機的一個Thread(Notify)或者是全部的Thread(NotifyALL)從Object Lock的wait set區(qū)域進入了entry set中。

(4)在當(dāng)前擁有鎖的線程釋放掉鎖的時候,處于該Object Lock的entryset區(qū)域的線程都會搶占該鎖,但是只能有任意的一個Thread能取得該鎖,而其他線程依然在entry set中等待下次來搶占到鎖之后再執(zhí)行。

當(dāng)獲取當(dāng)前鎖的線程離開同步區(qū),對象的鎖值減一,且鎖值為0(鎖可以重復(fù)進入,每次進入自加1),那么監(jiān)視器會釋放信息量,Entry_set隊列中的線程會搶鎖,只有一個線程可以獲取鎖。



總結(jié)

以上是生活随笔為你收集整理的对jvm 同步锁的理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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