Java鎖機制

問:爲何說java的syncronized關鍵字的效率很低? java

這是由於,java中線 程是映射到操做系統的原生線程上的。若是要喚醒或者是阻塞一條線程須要操做系統的幫忙。這就須要從用戶態轉換到核心態。所以,狀態轉換須要至關長的時間。 因此說syncronized關鍵字是java中比較重量級的操做。虛擬機自己會作一些優化。好比,在通知操做系統阻塞線程以前,加入一段自旋等待過程, 避免頻繁的切入到和心態中。 安全

除了syncronized關鍵字,java中還可使用java.lang.concurrent包中的ReentrantLock來實現同步。在基本用法上,兩者相似。可是ReentrantLock增長了一些高級特性,只要有如下三個: 多線程

第1、等待可中斷 jvm

第2、公平鎖 函數

第3、鎖綁定多個條件 性能

等待可中斷是指,等待的線程在等待超過必定時間以後,能夠選擇繼續等待,或者也能夠不等待直接去作其餘事情了。這對於執行時間很是長的同步塊來講頗有用。 優化

公平鎖是指,線程必須按照排隊的順序來得到鎖,而非公平鎖則不保證這一點。在非公平鎖中,任何一個等待的線程都有可能得到鎖。 spa

鎖綁定多個條件是指,一個 ReentrantLock對象能夠同時綁定多個Condition對象。而在syncronized中,鎖對象的wait和notify或者是 notifyall方法能夠實現一個隱含的條件,若是要和多於一個的條件進行關聯的時候,則不得不額外的添加一個鎖。ReentrantLock不須要額 外的添加一個鎖,只須要屢次調用newCondition()方法便可。 操作系統

與syncronized相比,ReentrantLock的性能能夠保持在一個比較穩定的水平。從java1.6開始,syncronized與ReentrantLock在性能上徹底持平了。因此在1.6以後,性能就不是選擇ReentrantLock的緣由了。 線程

---------------------------------------------------------------------------------------

鎖的優化

jvm針對鎖進行了一些優化

第1、自旋鎖和自適應自旋

第2、鎖消除

第3、鎖粗化

第4、輕量級鎖

第5、偏向鎖

其中,自旋鎖,是指線程在等待一個鎖的時候,不放棄cpu時間,而是在忙等。這個功能是有缺點的,好比說,等待時間過長,那麼自旋只會白白浪費cpu時間。若是等待時間很短,那麼自旋卻是頗有價值。

自適應自旋鎖因而誕生了。若是上一次自旋成功了,那麼自適應自旋鎖會認爲下一次等待也應該會成功,因而能夠適當的放寬自旋的等待時間。若是以前一直自旋失敗,那麼會省掉這個自旋過程,直接進入線程掛起。

鎖消除是指,根據代碼逃逸技術,若是判斷到一段代碼中,堆上的數據不會逃逸出當前線程,那麼能夠認爲這段代碼是線程安全的,沒必要要加鎖好比說String a="a"+"b",這段代碼中實際上是有鎖的【想一想StringBuffer】,可是編譯器把鎖給優化掉了。

鎖粗化,什麼是粗化??好比說String a="a"+"b"+"c",這裏實際上是有多個鎖操做的。可是在同一個函數裏面,是沒有代碼競爭的,根本就沒有必要進行鎖操做。因而,編譯器就能夠優化掉這部分鎖操做。

輕量級鎖,是JDK1.6新增的鎖機制。這裏的輕量級是針對須要操做系統互斥量來實現的傳統鎖而言的。所以傳統的鎖被稱做是「重量級鎖」。輕量級鎖並非用來取代重量級鎖的,他的本意是在沒有多線程競爭的狀況下,減小傳統的重量級鎖使用操做系統互斥量產生的性能損耗。

偏向鎖,也是1.6才引入的一項鎖優化。目的是爲了消除數據在無競爭的狀況下的同步原語。進一步提升程序的性能。偏 向鎖就是「偏袒」第一個得到這個鎖的線程,若是在接下來的執行過程當中,該鎖沒有被其餘線程獲取,那麼該線程將永遠不須要再次進行同步。可是當另一個線程 嘗試獲取該鎖的時候,偏向模式宣告結束。根據鎖定對象的當前狀態,撤銷偏向後恢復到未鎖定狀態或者是進入輕量級鎖定狀態。能夠看出,若是程序中大多數的鎖 都是被多個線程所訪問的,那麼偏向鎖就是多餘的。

相關文章
相關標籤/搜索