Sychronized中關(guān)于鎖的一些理解
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
jdk1.6中為了減少獲取鎖和得到鎖帶來的性能消耗,引入了偏向鎖和輕量級鎖。再java1.6中,鎖有四種狀態(tài)。
無鎖
偏向鎖
輕量級鎖
重量級鎖

偏向鎖(只適用于一個線程訪問的情景)
其實鎖是不存在多線程競爭的,且總是由同一線程多次獲得,為了讓線程獲得鎖的代價更低。引入了偏向鎖。當(dāng)一個線程訪問同步代碼塊并獲取鎖時,會在對象頭和棧幀中鎖記錄中記錄偏向鎖的線程id。當(dāng)以后該線程再進入同步代碼塊的時候,只需要簡單的測試對象頭里面的Mark Word的存儲結(jié)構(gòu)是否存儲著指向當(dāng)前線程的偏向鎖。如果,測試成功,那么久表示獲得了鎖。如果測試失敗,那么就需要測試一下偏向鎖的標(biāo)識是否設(shè)置了1,如果是1則嘗試使用CAS將對象頭的偏向鎖指向當(dāng)前線程,如果不是1則使用CAS競爭鎖。
偏向鎖使用了競爭出現(xiàn)才釋放鎖的機制,當(dāng)其他線程嘗試晶振偏向鎖時持有偏向鎖的線程菜會釋放鎖。而且需要等待全局安全點。安全點指的是,在這個時間點上沒有正在執(zhí)行的字節(jié)碼。撤銷的時候先檢查持有偏向鎖的線程是否還活著,如果線程不處于活動狀態(tài),則將對象頭設(shè)置為成無鎖狀態(tài)。如果線程仍然活著,擁有偏向鎖的棧會被執(zhí)行,遍歷偏向?qū)ο蟮逆i記錄,棧中的鎖記錄和對象頭的Mark Word要么重新偏向其他線程,要么恢復(fù)到無所或標(biāo)記對象不適合作為偏向鎖,最后喚醒。

輕量級鎖
加鎖:
線程在執(zhí)行同步塊之前,JVM會先在當(dāng)前線程的棧楨中創(chuàng)建用于存儲鎖記錄的空間,并將對象頭中的Mark Word復(fù)制到鎖記錄中,官方稱為Displaced Mark Word。然后線程嘗試使用CAS將對象頭中的Mark Word替換為指向鎖記錄的指針。如果成功,當(dāng)前線程獲得鎖,如果失敗,表示其他線程競爭鎖,當(dāng)前線程便嘗試使用自旋來獲取鎖。
解鎖:
輕量級解鎖時,會使用原子的CAS操作將Displaced Mark Word替換回到對象頭,如果成
功,則表示沒有競爭發(fā)生。如果失敗,表示當(dāng)前鎖存在競爭,鎖就會膨脹成重量級鎖。圖2-2是
兩個線程同時爭奪鎖,導(dǎo)致鎖膨脹的流程圖。

偏向鎖:加鎖和解鎖不需要額外的消耗,但是線程之間存在鎖競爭,鎖撤銷的時候消耗要大。
輕量級鎖:競爭的線程不會阻塞,提高了線程的響應(yīng)速度。如果始終得不到鎖,那么就會自旋消耗cpu。目的是為了追求相應(yīng)時間。
重量級鎖:不會使用自旋,不消耗cpu。線程阻塞,響應(yīng)慢,但是追求吞吐量。
————————————————
版權(quán)聲明:本文為CSDN博主「狗哥狗弟齊頭并進」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/qq_42674604/article/details/116061200
粉絲福利:Java從入門到入土學(xué)習(xí)路線圖
??????

??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
