Java:synchronized關鍵字引出的多種鎖
前言
Java 中的 synchronized
關鍵字可以在多執行緒環境下用來作為執行緒安全的同步鎖。本文不討論 synchronized
的具體使用,而是研究下synchronized
底層的鎖機制,以及這些鎖分別的優缺點。
一 synchronized機制
synchronized
關鍵字是JAVA中常用的同步功能,提供了簡單易用的鎖功能。
synchronized
有三種用法,分別為:
- 用在普通方法上,能夠鎖住當前物件。
- 用在靜態方法上,能夠鎖住類
- 用在程式碼塊上,鎖住的是
synchronized
()裡的物件
在JDK6之前,synchronized
使用的是重量級鎖制,在之後synchronized
synchronized
關鍵字的效率。
基於synchronized
關鍵字,我們來了解下幾種類別的鎖,並且講解synchronized
的鎖膨脹機制。
synchronized
鎖是非公平鎖。並且一個被synchronized
鎖住的物件或類,就是一把鎖。
另外一提,所有鎖都是儲存在Java物件頭裡的,Java物件頭裡的Mark Word裡預設儲存物件的HashCode,分代年齡和鎖標記位。也就是說Mark Word記錄了鎖的狀態
二 鎖膨脹機制與幾類鎖
鎖膨脹是不可逆的
2.1 偏向鎖
synchronized
在JDK1.6以後預設開啟偏向鎖
,synchronized
最初都是偏向鎖
表現:一個執行緒獲取鎖成功後,會在物件頭裡記錄執行緒ID,以後該執行緒獲取和釋放鎖都沒有任何花費。(因為該鎖已經被繫結在該執行緒上了,且在膨脹前不會改變),如果其他執行緒嘗試獲取這個鎖,偏向鎖
將會膨脹為輕量鎖
。
優點:在只有一個執行緒使用鎖的時候獲取和退出鎖沒有任何花費
缺點:鎖競爭激烈會很快升級為輕量鎖
,那麼維持偏向鎖
的過程就是在浪費計算機資源。(不過因為偏向鎖
本身就很輕量,因此浪費的資源並不多)
小結:只有一個執行緒使用鎖的情況下,synchronized
使用的鎖為偏向鎖
。
如果鎖競爭激烈,可以通過配置JDK禁用偏向鎖
。
2.2 輕量鎖
一把鎖不止一個執行緒使用,則
偏向鎖
膨脹為輕量鎖
表現:執行緒獲取輕量鎖
時,會直接用CAS
修改物件頭裡鎖的記錄,如果修改失敗,代表此時鎖存在多個執行緒的競爭,輕量鎖
將會膨脹為重量鎖
。
優點:線上程之間使用鎖不存在競爭時,一次CAS
操作就能獲取和退出鎖
缺點:與偏向鎖
類似
小結:只要一把鎖不止一個執行緒獲取過,偏向鎖
就會膨脹為輕量鎖
。
2.3 重量鎖
一把鎖存在多執行緒競爭,則
輕量鎖
開始自旋,自旋一定次數後仍沒獲取鎖,則膨脹為重量鎖
(存在競爭時,輕量鎖
雖然會先自旋,但是最終往往都會膨脹為重量鎖
)
表現:執行緒獲取重量鎖
時,如果獲取失敗(即鎖已被其他執行緒獲取),則使用自適應自旋鎖
,自旋一定次數後仍沒獲取鎖,則進入阻塞佇列等待。
優點:未獲取到的鎖進入阻塞佇列,節約CPU資源。(好吧感覺其實是沒有啥優點)
缺點:重量鎖
是通過物件內部的監視器(monitor)實現,其中monitor的本質是依賴於底層作業系統的Mutex Lock實現,作業系統實現執行緒之間的切換需要從使用者態到核心態的切換,切換成本非常高。
小結:只要一把鎖存在多執行緒競爭,輕量鎖
就會膨脹為重量鎖
。
自旋鎖
synchronized
的輕量鎖
,重量鎖
,使用了自適應自旋鎖
進行效能優化
首先介紹自旋鎖
表現:執行緒獲取鎖失敗後,不會進入阻塞等待,而是再次嘗試去獲取鎖,如此反覆,直到獲取到鎖,或者自旋結束那麼會阻塞等待。
解決問題:在某些場景下,執行緒持有鎖的時間非常短。線上程獲取鎖失敗後,如果執行緒進入阻塞將會帶來執行緒上下文的切換,上下文切換的時間可能反而高於執行緒反覆嘗試獲取鎖的時間。
此時執行緒原地等待去重複獲取鎖。反而在效能上更有優勢。
缺點:
- 單核CPU沒有執行緒並行,反覆嘗試會導致程序無法繼續執行。
- 重複嘗試導致了CPU的佔用,如果CPU資源緊張的話反而會效能下降
- 如果鎖的競爭時間過長,不僅沒有效能提升,還浪費了大量CPU資源。
優化:使用自適應自旋鎖
。自適應自旋鎖會根據之前的鎖獲取記錄,優化調整自旋時間,避免造成不必要的自旋。
三 具體synchronized流程
相關推薦
Java:synchronized關鍵字引出的多種鎖
前言 Java 中的 synchronized關鍵字可以在多執行緒環境下用來作為執行緒安全的同步鎖。本文不討論 synchronized 的具體使用,而是研究下synchronized底層的鎖機制,以及這些鎖分別的優缺點。 一 synchronized機制 synchronized關鍵字是JAVA中常用的
Java多執行緒synchronized關鍵字引出的多種鎖
一、synchronized機制 synchronized關鍵字是JAVA中常用的同步功能,提供了簡單易用的鎖功能。 synchronized有三種用法,分別為: 用在普通方法上,能夠鎖住當前物件。 用在靜態方法上,能夠鎖住類 用在程式碼塊上,鎖住的是synchronized()裡的物件 在JDK6之前
JAVA synchronized關鍵字鎖機制(中)
就會 16px ride tar rac 效果 sync 靜態方法 訪問 synchronized 鎖機制簡單的用法,高效的執行效率使成為解決線程安全的首選。 下面總結其特性以及使用技巧,加深對其理解。 特性: 1. Java語言的關鍵字,當它用來修飾一個方法或者一個代
java synchronized關鍵字的用法以及鎖的等級:方法鎖、物件鎖、類鎖
轉載自:http://blog.csdn.net/le_le_name/article/details/52348314 java的內建鎖:每個java物件都可以用做一個實現同步的鎖,這些鎖成為內建鎖。執行緒進入同步程式碼塊或方法的時候會自動獲得該鎖,在退出同步程式碼塊
java synchronized關鍵字的底層實現
重排序 代碼 logs this 底層實現 com 實現 alt 關鍵字 每個對象都有一個鎖(Monitor,監視器鎖),class對象也有鎖,如果synchronized關鍵字修飾同步代碼塊,通過反編譯可以看到,其實是有個monitorenter和monitorexit指
java synchronized關鍵字在jvm中的實現原理
為了實現共享資源的執行緒安全,我們常常會使用synchronzied關鍵字來為資源加鎖,在一個執行緒操作資源的時候,將資源鎖住只供自己使用。這樣保證了執行緒使用資源的同步,避免了對資源同時讀寫造成讀寫結果異常的情況。 那麼,synchronized關鍵字在我們的jvm中具體是怎麼實現的呢
Java synchronized關鍵字使用小結
1. 在編寫一個類時,如果該類中的程式碼可能執行與多執行緒環境下,就要考慮同步問題了。會同時被多個執行緒訪問的資源,就是競爭資源,也稱為競爭條件。對於多執行緒共享的資源我們必須進行同步,以避免一個執行緒的改動被另一個執行緒所覆蓋。synchronized 關鍵字有兩種作用域:
java synchronized 關鍵字(1)物件監視器為Object
在java多執行緒中 synchronized 是非常重要的,也是經常用到的 對於synchronized關鍵字要注意兩點 synchronized物件監視器為Object的時候 synchronized物件監視器為Class的時候 物件監視器為
關於java synchronized關鍵字的一些理解
看了java程式設計思想的併發這一章,發現對於synchronized關鍵字理解不夠到位,看了其他人的部落格,加深了一些理解:http://www.cnblogs.com/GnagWang/archi
Android進階——多執行緒系列之wait、notify、sleep、join、yield、synchronized關鍵字、ReentrantLock鎖
前言 多執行緒一直是初學者最困惑的地方,每次看到一篇文章,覺得很有難度,就馬上叉掉,不看了,我以前也是這樣過來的。後來,我發現這樣的態度不行,知難而退,永遠進步不了。於是,我狠下心來看完別人的部落格,儘管很難但還是咬著牙,不懂去查閱資料,到最後弄懂整個過程。雖
Java synchronized 關鍵字詳解
Java synchronized 關鍵字詳解 前置技能點 程序和執行緒的概念 執行緒建立方式 執行緒的狀態狀態轉換 執行緒安全的概念 synchronized 關鍵字的幾種用法 修飾非靜態成員方法 synchronized public void sync(){ } 修飾靜態成員方法 synchro
java線程總結--synchronized關鍵字,原理以及相關的鎖
public 關鍵字 多線程 java 文章 在多線程編程中,synchronized關鍵字非常常見,當我們需要進行“同步”操作時,我們很多時候需要該該關鍵字對代碼塊或者方法進行鎖定。被synchronized鎖定的代碼塊,只能同時有一條線程訪問該代碼塊。上面是很多人的認識,當然也是我之前
java執行緒總結--synchronized關鍵字,原理以及相關的鎖
在多執行緒程式設計中,synchronized關鍵字非常常見,當我們需要進行“同步”操作時,我們很多時候需要該該關鍵字對程式碼塊或者方法進行鎖定。被synchronized鎖定的程式碼塊,只能同時有一條執行緒訪問該程式碼塊。 上面是很多人的認識,當然也是我之前對synchronized關鍵字的淺
Java併發——synchronized關鍵字,內建鎖解析,可見性,互斥性淺談
Java中為了保證每個執行緒中的原子操作,引入了內建鎖,或者稱為監視器鎖,其中,每個Java物件都可以作為一個實現鎖的物件,synchronized關鍵字修飾的程式碼塊被稱為同步程式碼塊,執行緒進入同步程式碼塊自動獲取內建鎖,退出同步程式碼
Java併發——Synchronized關鍵字和鎖升級,詳細分析偏向鎖和輕量級鎖的升級
一、Synchronized實現原理 1、Synchronized鎖的3中形式: Synchronized修飾普通同步方法:鎖物件當前例項物件; Synchronized修飾靜態同步方法:鎖物件是當前的類Class物件; Synchronized修飾同步程式碼塊:鎖物
Java物件鎖和類鎖全面解析(多執行緒synchronized關鍵字)
最近工作有用到一些多執行緒的東西,之前吧,有用到synchronized同步塊,不過是別人怎麼用就跟著用,並沒有搞清楚鎖的概念。最近也是遇到一些問題,不搞清楚鎖的概念,很容易碰壁,甚至有些時候自己連用沒用對都不知道。 今天把一些疑惑都解開了,寫篇文章分享給大家
JAVA多執行緒之Synchronized關鍵字--物件鎖的特點
一,介紹 本文介紹JAVA多執行緒中的synchronized關鍵字作為物件鎖的一些知識點。 所謂物件鎖,就是就是synchronized 給某個物件 加鎖。關於 物件鎖 可參考:這篇文章 二,分析 synchronized可以修飾例項方法,如下形式: 1 public class My
Java多線程synchronized關鍵字
print static sync log nbsp 關鍵字 public true current synchronized關鍵字代表著同步的意思,在Java中被synchronized修飾的有三種情況 1.同步代碼塊 //鎖為objsynchronized(obj){
java基礎回顧(五)線程詳解以及synchronized關鍵字
dom com stack 相互 ++ 關於 而是 。。 str 本文將從線程的使用方式、源碼、synchronized關鍵字的使用方式和陷阱以及一些例子展開java線程和synchronized關鍵字的內容。 一、線程的概念 線程就是程序中單獨順序的流控制。線程本 身不能
Java中synchronized關鍵字理解
監視器 pre 定義 exc 執行 zed 三種 gen 好記性不如爛筆頭 好記性不如爛筆頭~~ 並發編程中synchronized關鍵字的地位很重要,很多人都稱它為重量級鎖。利用synchronized實現同步的基礎:Java中每一個對象都可以作為鎖。具體表現為以下三種形