1. 程式人生 > >十二、JVM(HotSpot)執行緒安全與鎖優化----終結篇

十二、JVM(HotSpot)執行緒安全與鎖優化----終結篇

注:本博文主要是基於JDK1.7會適當加入1.8內容。

執行緒安全:當多個執行緒訪問一個物件時,如果不用考慮這些執行緒在執行環境下的排程和交替執行,也不需要進行額外的同步,或者在呼叫方進行任何其他的協調操作,呼叫這個物件的行為可以獲取正確的結果,那這個物件就是執行緒安全的。

1、Java語言中執行緒安全

  • 不可變(final關鍵字)
  • 絕對執行緒安全(Vector、HashTable非絕對執行緒安全,集合裡面還包裹著物件)
  • 相對執行緒安全(JDK標註為執行緒安全的一些類Vector、HashTable等)
  • 相對執行緒安全(通過一些同步方法保證執行緒安全,如HashMap、ArrayList等)
  • 執行緒對立(無論呼叫方是否採用了同步措施,都無法再多執行緒環境中併發使用,Thread類中suspend和resume方法,已被棄用)

2、執行緒安全實現方法

  • 互斥同步(synchronized和ReentrantLock)—-悲觀
    同步是指多個執行緒併發訪問共享資料時,保證共享資料在同一個時刻只能被一個執行緒使用,而互斥是實現同步的一個手段。臨界區(Critical Section)、互斥量(Mutex)和共享量(Semaphore)都是主要互斥實現方式。互斥是因,同步是果;互斥是方法,同步是目的。
    -非阻塞同步(CAS可能產生ABA問題和Version)—-樂觀
    -無同步方案:可重入程式碼和執行緒本地儲存(ThreadLocal)

3、鎖優化

(1)自旋鎖和自適應自旋

執行緒互斥同步時,掛起和恢復執行緒的操作都需要轉入核心態完成,併發效能壓力大。如果共享資料的鎖定狀態很短,為了這段時間去掛起和恢復顯然不值得,物理機器有一個以上的CPU能讓兩個或以上執行緒同時併發執行,我們可以讓另一個執行緒稍微等一等,但不放棄CPU處理時間,為了執行緒等待,我們只需要讓執行緒執行一個忙迴圈(自旋),這項技術就是自旋,預設自旋次數為10。

自適應自旋是JDK1.6引入,由起那一次在同一個鎖上的自選時間及鎖擁有者決定

(2)鎖消除

虛擬機器即時編譯器執行時,對一些程式碼要求同步,但是被檢測到不可能存在共享資料晶振的鎖進行消除。

(3)鎖粗化

(4)輕量級鎖

對於絕大部分的鎖,整個同步週期內都不存在競爭的。如果沒有競爭,輕量級鎖使用CAS操作避免了使用互斥量的開銷,如果存在鎖競爭,除了互斥量的鎖競爭開銷外,還額外發生CAS操作。

(5)偏向鎖-XX:+UseBiasedLocking

可以提升帶有同步但無競爭的程式效能,如果程式中大多數鎖總是被多個不同的執行緒訪問,那偏向鎖模式是多餘。