面試連環炮系列(三):synchronized怎么用的


  1. synchronized怎么用的?
    用過,synchronized是常用的並發控制關鍵字,簡單的說就是訪問加鎖。它可以修飾靜態方法或者一個類的class對象,這叫類鎖;可以修飾普通方法或者代碼塊,這叫對象鎖。

  2. synchronized是可重入鎖嗎?
    從互斥鎖的設計上來說,當一個線程試圖操作一個由其他線程持有的對象鎖的資源時,將會處於阻塞狀態,但當一個線程再次請求自己持有對象鎖的資源時,這種情況屬於重入鎖,請求將會成功。java中synchronized是基於原子性的內部鎖機制,是可重入的。

  3. synchronized的實現原理了解過嗎?
    synchronized使用了monitorenter和monitorexit指令實現同步,這兩個指令本質上都是對一個對象的監視器(monitor)進行獲取。這個過程是排他的,同一時刻只能有一個線程獲取到由synchronized所保護對象的監視器。線程執行到monitorenter指令時,會嘗試獲取對象所對應的monitor所有權,也就是嘗試獲取對象的鎖,而執行monitorexit,就是釋放monitor的所有權。

  4. 能說說synchronized的鎖升級嗎?
    jdk1.6以后對synchronized的鎖進行了優化,鎖的級別從低到高逐步升級:無鎖->偏向鎖->輕量級鎖->重量級鎖。但是鎖的升級是單向的,只能從低到高升級,不會降級。JVM中對象在內存中的布局分為三塊區域:對象頭、實例變量和填充數據。對象頭主要包括兩部分數據:Mark Word(標記字段)、Klass Pointer(類型指針)。Mark Word用於存儲對象自身的運行時數據,它是實現輕量級鎖和偏向鎖的關鍵。

    1. 如果一個線程獲得了鎖,鎖就進入偏向模式,此時Mark Word的結構變為偏向鎖結構,當這個線程再次請求鎖時,無需再做任何同步操作,這樣就省去了大量有關鎖申請的操作,提高了程序的性能。
    2. 在鎖競爭激烈的場合,每次申請鎖的線程都是不相同的,偏向鎖就失效了,偏向鎖失敗后升級為輕量級鎖。輕量級鎖是相對於使用操作系統互斥量來實現的傳統鎖而言的,它所適應的場景是線程交替執行同步塊,如果存在同一時間訪問同一鎖的情況,就會膨脹為重量級鎖。
    3. 輕量級鎖失敗后,還會進行自適應自旋。大多數情況下線程持有鎖的時間都不會太長,如果操作系統層面直接掛起,線程之間的切換時需要從用戶態轉換到核心態,這個狀態的轉換需要比較長的時間。自旋鎖假設在當前的線程很快可以獲得鎖,虛擬機會讓當前線程做50個循環或100循環空循環。在經過若干次循環后,如果得到鎖就順利進入臨界區。如果還不能獲得鎖就會將線程掛起,升級為重量級鎖了。注意,JVM還會自動調整自旋次數,這次成功了,下次自旋的次數會多;如果失敗了,下次自旋的次數就會減少。

參考文章:

https://blog.csdn.net/u011212394/article/details/82228321
https://www.cnblogs.com/fuly550871915/p/4890753.html
https://www.cnblogs.com/paddix/p/5405678.html

雞湯:不要因為走得太遠,忘了我們為什么出發。— 紀伯倫


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM