Synchronized ,Volatile,Lock 三者不可告人的祕密
前言
傳說天地初開,Synchronized ,Volatile,Lock孕育而生,他們之間有著怎麼樣的精彩故事呢?這篇文章,輝先森與你一同看看。
一、Synchronized ,Volatile,Lock出現的場景
他們的出現是為了解決執行緒安全問題。注意了,執行緒安全不是指執行緒的安全,而是指記憶體的安全,所以多執行緒的通訊要保證的也是記憶體資料的安全。簡單的說明一下原因:
在目前主流的作業系統中,每個程式都有自己的記憶體空間,而不能去訪問其他程式的,這是有作業系統進行保證的啊,就是每個程式都有相同的邏輯空間,但是資料怎麼存在真實的物理空間裡面,這是有我們的作業系統去解決(分頁,分段)。
執行緒是工作在程式之下的,而我們程式的堆記憶體是程式內的所以執行緒都可以訪問到的區域。這就會造成一個問題,比如,某個執行緒正在辛辛苦苦的處理資料,這時他被老闆叫去開會,回來發現,資料被改動過了。我們把堆記憶體理解成程式通訊的共享記憶體就很容易理解了,大家都可以訪問你這個記憶體地址,我又不知道這是不是有人在用,所以就需要我們鎖的出現。
二、Synchronized的原理
Synchronized關鍵字的作用:
這是一個同步鎖的概念,被Synchronized修飾的程式碼段可防止被多個執行緒同時執行,必須一個執行緒把Synchronized修飾的程式碼段都執行完畢了,其他執行緒才能開始執行這段程式碼。保證了可見性,原子性,有序性。
Synchronized的工作原理:
1. 物件被建立在堆記憶體中的,物件在記憶體中的佈局可分成3塊區域:物件頭,例項資料,對齊填充。
例項資料:存放類的屬性資料資訊,包括父類的屬性資訊。
對齊填充:這是由於JVM要求物件初始地址是8位元組的整數倍。
物件頭是Synchronized實現鎖的基礎,主要的結構是有Mark Word 和 型別指標。
Mark Word :儲存物件的hashcode,鎖資訊或分代年齡等。
型別指標:指向物件的類後設資料,JVM是通過該指標去確定物件是哪個類的例項。
2. 每一個鎖都對應一個monitor物件的起始地址。每個物件例項都會有一個monitor,這是與物件一起建立銷燬或者是執行緒獲得物件鎖時自動生成的。當一個monitor被某執行緒持有後,便處於鎖定狀態了。
monitor:可以理解為一個同步工具或者一種同步機制,通常被描述為一個物件。monitor是執行緒私有的資料結構,每一個執行緒都有一個可用的monitor record列表和一個全域性可用列表。每一個鎖住的物件都會和一個monitor關聯,同時monitor有一個owner欄位存放擁有該鎖的執行緒唯一標識,表示該鎖被這個執行緒佔用了。
3. Synchronized常被用於修飾程式碼塊或者方法,我們看看這個兩者有什麼區別。
Synchronized修飾程式碼塊:底層是使用了monitorenter 和 monitorexit 指令。 當執行monitorenter指令時,會嘗試獲得monitor物件,成功就把鎖的計數器_count加1,當執行到 monitorexit 指令時,計數器就減1。
這裡雖然沒有貼原始碼,但是讀者看原始碼是可以知道是會出現兩個monitorexit 指令,這可能會讓我們有點困惑,講道理monitorenter 和 monitorexit 指令應該是一同出現的吧,那為什麼會出現兩個monitorexit 指令呢?
其實啊,這是為了保證在方法異常時,monitorenter 和 monitorexit 指令也是可以配對執行,編譯器會自動產生一個異常處理器,目的是用來執行異常的monitorexit 指令去釋放monitor。
Synchronized修飾方法:是用ACC_SYNCHRONIZED標識,JVM會通過該標識去執行上面的同步過程二、Synchronized的優化
三、Synchronized的優化
在JDK1.5之前Synchronized的效率是很低的,這是因為底層的monitorenter 和 monitorexit 指令都是執行在核心態的,而使用者態去到核心態的時間開銷是不低的。以至於在JDK1.5,引入了Synchronized的新概念:無鎖,偏向鎖,輕量級鎖,重量級鎖。這些只是使用Synchronized鎖後的一種鎖狀態,儲存的地方就是開頭介紹的Mark Word中。
這裡先不講這四種狀態的介紹,我們留到之後在來開一片JAVA鎖的全家桶。現在我們只需要先知道,鎖的狀態的等級:無鎖<偏向鎖<輕量級鎖<重量級鎖。鎖的狀態只能從低等級的升級到高等級,而不能反向,也就是說升級的方向是:無鎖->偏向鎖->輕量級鎖->重量級鎖。
優化的重點來了,前面搞這麼多的鎖狀態其實就是要優化解決Synchronized頻繁的從使用者態到核心態的轉移。真正會進入到核心態的是升級到重量級鎖時。 這也是現在Synchronized的效能可以和Lock交手的原因。
四、volatile和Synchronized 的區別
volatile關鍵字的作用:
保證可見性和有序性(不保證原子性),如果一個變數被volatile修飾我們稱為共享變數,那一個執行緒修改了這個共享變數後,其他執行緒是立馬可以知道的。因為該變數會強制立刻重新整理到主存。
禁止指令重新排序,在volatile變數之前的指令不能在volatile變數之後執行,在volatile變數之後的指令不能在volatile變數之前執行。(使用場景可以看看單例模式的雙重校驗鎖機制)。
volatile和Synchronized 的區別:
(1)volatile只能作用與變數,使用範圍較小。Synchronized 可以用在變數,方法,類,同步程式碼塊等,使用廣。
(2)volatile保證可見性和有序性(不保證原子性),而Synchronized都保證。
(3)volatile不會造成執行緒阻塞,Synchronized可能會造成執行緒阻塞。
五、Lock和Synchronized 的區別
Lock關鍵字的作用:
Lock和Synchronized差不多,只是一個是有程式設計師手動去釋放鎖(Lock),一個是由JVM去自動釋放鎖(Synchronized)。
Lock和Synchronized 的區別:
(1)用法不同:Synchronized是託管於JVM會自動的釋放鎖,而Lock需要我們顯示的指定頭尾。
(2)效能:在JDK1.5之後兩者差不多了,可能還是lock會快一點點吧。
(3)底層不同:Synchronized是悲觀鎖,最終基於作業系統的mutex lock來實現互斥;Lock是樂觀鎖,CAS+volatile。
(4)功能:Lock提供高階功能實現:可定時,可輪詢,可中斷,讀寫鎖,公平鎖或者非公平鎖。而Synchronized只是一個普通的非公平鎖。但是他們兩者都是可重入鎖。
總結
程式設計世界博大精深,需要我們細細品味,好好學習,共同進步,加油少年郎。對了,差點忘記怎麼暴打面試官了,當你可以理解這篇文章了,被問到Synchronized時,嘻嘻,就是在送。
相關文章
- java裡的鎖總結(synchronized隱式鎖、Lock顯式鎖、volatile、CAS)Javasynchronized
- volatile與synchronized的區別synchronized
- synchronized和volatile的區別synchronized
- synchronized 與 Lock 的對比synchronized
- Lock 和 synchronized的區別synchronized
- synchronized與Lock的區別synchronized
- 四、Synchronized與Lock原理synchronized
- 向xxxhub發了一個資料包,發現了一些不可告人的祕密
- Lock、Synchronized鎖區別解析synchronized
- Volatile關鍵字&&DCL單例模式,volatile 和 synchronized 的區別單例模式synchronized
- 全面解讀volatile和synchronize,輕鬆掌握Volatile與Synchronizedsynchronized
- 淺談synchronized、Lock、ThreadLocal和semaphoresynchronizedthread
- 理解並正確使用synchronized和volatilesynchronized
- Java併發2:JMM,volatile,synchronized,finalJavasynchronized
- synchronized與Lock的區別與使用詳解synchronized
- synchronized Lock(本地同步)鎖的8種情況synchronized
- synchronized底層揭祕synchronized
- JUC之Lock介面以及Synchronized回顧synchronized
- 打工人,從 JMM 透析 volatile 與 synchronized 原理synchronized
- Eventloop的祕密OOP
- 【JavaSE】Lock鎖和synchronized鎖的比較,lock鎖的特性,讀寫鎖的實現。Javasynchronized
- Java培訓教程之使用Lock取代synchronizedJavasynchronized
- 多執行緒基礎之synchronized和volatile執行緒synchronized
- Java併發指南4:Java中的鎖 Lock和synchronizedJavasynchronized
- 既然synchronized是"萬能"的,為什麼還需要volatile呢?synchronized
- 從JMM透析volatile與synchronized原理,圖文並茂synchronized
- 關於NSUserDefaults的祕密
- 隨機森林的祕密隨機森林
- 網頁文字的祕密網頁
- 隱藏在水印的祕密
- ZooKeeper 會話的祕密會話
- Java中的執行緒安全:從synchronized到Lock的深入理解Java執行緒synchronized
- 詳解鎖原理,synchronized、volatile+cas底層實現synchronized
- Redis小祕密Redis
- “==”、“equals()”、“hashcode()”之間的祕密
- 挖掘Chrome Console的小祕密Chrome
- 揭示檢查點的祕密
- TCP/IP家族的小祕密TCP