亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java對于對象鎖是如何管理的?

java對于對象鎖是如何管理的?

HUH函數 2018-09-03 19:11:50
我在看一本多線程的書時, 上面說java對于每個對象鎖都有兩個隊列, 一個就緒隊列, 一個等待隊列. 我聯想到操作系統對于進程資源的管理, 操作系統只有一個就緒隊列, 對于不同的資源有不同的等待隊列. 因此我對書上的這句話很懷疑, java對于對象鎖是怎么管理的呢?
查看完整描述

1 回答

?
千萬里不及你

TA貢獻1784條經驗 獲得超9個贊

每個鎖對象都有兩個隊列,一個是就緒隊列,一個是阻塞隊列,就緒隊列存儲了將要獲得鎖的線程,阻塞隊列存儲了被阻塞的線程,當一個被線程被喚醒 (notify)后,才會進入到就緒隊列,等待獲得鎖。你說的等待隊列也就是阻塞隊列。

例如:當一開始線程a第一次執行對象account.add()方法時,JVM會檢查鎖對象account的就緒隊列是否已經有線程在等待,如果有則表明account的鎖已經被占用了,由于是第一次運行,account的就緒隊列為空,所以線程a獲得了鎖, 執行account.add方法。如果恰好在這個時候,線程b要執行account.withdraw方法,因為線程a已經獲得了鎖還沒有釋放,所以線程b要進入account的就緒隊列,等到得到鎖后才可以執行。一個線程執行臨界區代碼過程如下:

1.獲得同步鎖2.清空工作內存3.從主存拷貝變量副本到工作內存4.對這些變量計算5.將變量從工作內存寫回到主存6.釋放鎖

可見,synchronized既保證了多線程的并發有序性,又保證了多線程的內存可見性。notify 不會釋放鎖,而是通知鎖對象的阻塞隊列里的某一線程(被阻塞,即主動調用wait方法),進入就緒隊列。線程釋放鎖的方式,通常是 主動調用wait方法、同步代碼塊結束釋放鎖資源。notifyall 是 喚醒阻塞隊列里的所有阻塞線程,他們都將進入就緒隊列,而notify的數量是一個。同步代碼塊結束釋放鎖資源,對象就緒隊列中的某一線程獲得鎖資源而開始線程;如果不使用notify 那么阻塞隊列 里 線程將一直處于阻塞狀態,即使就緒隊列里 線程都執行完了,阻塞隊列 里 線程也將一直處于阻塞狀態.某一線程釋放鎖之后,將會從就緒隊列中 隨機找出?(有疑問) 一線程,使之獲得鎖資源。


查看完整回答
反對 回復 2018-09-16
  • 1 回答
  • 0 關注
  • 857 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號