1. 程式人生 > >偏向鎖、輕量級鎖、重量級鎖的升級

偏向鎖、輕量級鎖、重量級鎖的升級

這幾個鎖之間的關係和升級需要理解,重量級鎖的獲取和釋放的開銷比較大,所以不能在任何情況下都加上重量級鎖;單執行緒的情況下鎖是可以不需要的,但是需要有應對多執行緒的方案(鎖升級);多個執行緒爭奪鎖,如果讓一個執行緒稍微等一等能解決的問題就不要用重量級鎖來完成。jvm中的的執行緒的排程由使用者執行緒是完成不了的,需要使用核心執行緒才能夠完成。重量級鎖的開銷主要是線上程從使用者狀態和核心狀態之間的切換,java獲取鎖時,先從使用者級執行緒切換到核心級執行緒去核心中獲取鎖,如果獲取到鎖就會切換回到使用者級執行緒,如果沒有獲取到就阻塞在核心中等待被喚醒。當使獲取到鎖的執行緒使用完成以後釋放鎖就會切換回到核心級執行緒去喚醒阻塞在核心的執行緒然後切換回使用者執行緒。所以一次獲取鎖的過程將會發生四次的執行緒狀態切換,開銷比較大。為了解決這個問題所以對鎖進行優化:    偏向鎖:單個執行緒下是不需要加鎖的。它是根據的經驗資料得來的依據,鎖在大多數情況下是不存在競爭的並且是由同一個執行緒獲得(也就是它是在單個執行緒下使用),因此引入了偏向鎖,偏向第一個執行緒,偏向鎖不會主動釋放,它是在發生鎖競爭的時候才會釋放,如果一個鎖物件前面被一個執行緒使用了,第二個執行緒來的時候會去檢測是不是自己持有這把鎖,如果是直接進入同步區域,如果不是則會判斷持有鎖的執行緒是否任然存活,如果是則需要發生鎖升級升級成輕量級鎖。輕量級鎖:能讓執行緒稍微等一等就能解決的問題就別用鎖。
它是一個比偏向鎖級別高的鎖,可以從偏向鎖升級而來,這個鎖物件是由持有的執行緒主動釋放,如果一個執行緒持有一把鎖的時候,另外一個執行緒來獲取同一把鎖,如果失敗將會自旋等待,而不是掛起執行緒,從而減小開銷。如果執行緒通過自旋獲取鎖失敗了那麼鎖才會升級成為重量級鎖。鎖升級的過程:1.假設剛開始A執行緒獲取鎖的時候第一次使用CAS操作來獲取偏向鎖;2.第二個B執行緒來了檢驗是不是自己擁有這把偏向鎖,如果是直接使用,如果不是通過CAS操作來獲取鎖,如果失敗(因為A執行緒正在使用當中並且A執行緒任然存活,發生鎖競爭)則將鎖升級成為輕量級鎖;3.升級成為輕量級鎖之後,執行緒B會使用自旋的方式來獲取這個鎖,如果B通過自旋的方式也一直獲取不到鎖,那麼鎖將會升級成為重量級鎖,執行緒通過阻塞等待獲取資源。