目錄
- Java記憶體模型
- 關于執行緒安全
- Volatile關鍵字
- Synchronized關鍵字
- 鎖的分類
- 輕量級鎖&重量級鎖
- 可重入鎖&不可重入鎖
- 讀寫鎖
- 樂觀鎖與悲觀鎖
- 樂觀鎖(適合多讀場景)
- 悲觀鎖(適合多寫場景)
- CAS無鎖機制
Java記憶體模型
Java記憶體模型(JMM)主要目標是定義多執行緒的情況下執行緒訪問變數的規則,
JMM規定執行緒之間的共享變數存盤在主記憶體中,每個執行緒都有一個本地記憶體(作業記憶體),本地記憶體存盤了共享變數的副本,

關于執行緒安全
-
什么是執行緒安全問題?
當多個執行緒同時共享同一個全域變數做寫的操作時候,可能會受到其他執行緒的干擾,導致資料臟讀,(資料一致性問題)
-
如何解決執行緒安全問題?
核心思想:在同一時刻,只能有一個執行緒執行,
通過加鎖使執行緒更加安全,也使程式的執行效率更低,
-
衡量執行緒安全的3個要素:
- 原子性:一個操作或者多個操作要么全部執行,要么都不執行
- 可見性:多個執行緒訪問同一變數,一個執行緒修改了變數的值,其他執行緒可以立即看到修改的值
- 有序性:程式按照代碼的順序先后執行(與指令重排有關)
Volatile關鍵字
volatile是一種輕量級的同步機制,可以保證可見性【及時將修改的變數重繪到主記憶體中】,但不能保證原子性,并且禁止重排序,
volatile在多執行緒下的適用場景:一寫多讀
volatile如何保證記憶體可見性?
當一個執行緒對volatile修飾的變數進行寫操作時,該執行緒中的本地記憶體的變數會被立刻重繪到主記憶體中,
當一個執行緒對volatile修飾的變數進行讀操作時,該執行緒直接讀取主記憶體的變數,
volatile能否保證執行緒安全?
不能,保證執行緒安全需要同時具備原子性,可見性和有序性,而volatile只能保證可見性和有序性,無法保證原子性,
Synchronized關鍵字
核心思想:在多執行緒執行同一個方法時,只有獲取到鎖,才能進入方法里面執行
使用方式:
- 修飾一個類:其作用的范圍是synchronized后面括號括起來的部分,作用的物件是這個類的所有物件;
- 修飾一個方法:被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的物件是呼叫這個方法的物件;
- 修飾一個靜態的方法:其作用的范圍是整個方法,作用的物件是這個類的所有物件;
- 修飾一個代碼塊:被修飾的代碼塊稱為同步陳述句塊,其作用范圍是大括號{}括起來的代碼塊,作用的物件是呼叫這個代碼塊的物件;
鎖的分類
輕量級鎖&重量級鎖
輕量級鎖:手動上鎖解鎖,擴展性強,代表:Lock
重量級鎖:自動上鎖解鎖,封裝程度高,代表:Synchronized
可重入鎖&不可重入鎖
可重入鎖(遞回鎖):當一個執行緒已經獲取到鎖后,再次請求該鎖,就可直接獲取,(鎖的傳遞,鎖的嵌套)代表:Synchronized,Lock
鎖的可重入性避免了大部分死鎖情況的產生
不可重入鎖:不具備傳遞性
讀寫鎖
ReentrantReadWriteLock
相對Synchronized效率更高,但在多執行緒情況下,只支持讀讀共存,不支持讀寫,寫寫,
樂觀鎖與悲觀鎖
樂觀鎖(適合多讀場景)
-
思想:認為不會發生執行緒沖突(本質上是沒有鎖的)
-
執行流程,先讀取資料,然后在更新前檢查在讀取至更新這段時間資料是否被修改
- 未修改:直接更新資料
- 已修改:重新讀取,再次提交更新(或者放棄操作)
為什么樂觀鎖適合多讀場景?
樂觀鎖是一種更新前的檢查機制,相對于悲觀鎖來說在多讀場景下可以減少鎖的性能開銷,對于多寫場景,樂觀鎖會一直進入已修改,重新讀取,再次提交的回圈,反而帶來更多的資源消耗,
悲觀鎖(適合多寫場景)
-
思想:認為一定會發生執行緒沖突
-
執行流程:讀取資料的時候上鎖(其他用戶無法讀取),直到本次資料更新完成才會釋放鎖,在多寫場景下,能保證較高的資料一致性,
【總的來說,樂觀鎖回滾重試,悲觀鎖阻塞事務】
CAS無鎖機制
原子類:AtomicBoolean,AtomicInteger,AtomicLong,AtomicReference可保證執行緒安全,底層使用CAS無鎖機制
CAS:Compare and Swap,比較再交換,屬于樂觀鎖的一種
-
CAS原理
CAS包含3個引數,CAS(V,E,N),V:主記憶體的變數值,E:本地記憶體修改前的值,N:本地記憶體修改后的值
比較主記憶體的值和本地記憶體修改前的值是否一致,若一致,將修改后的值重繪到主記憶體,若不一致,當前執行緒放棄更新,將主記憶體資料重繪到本地記憶體,再次重試,
-
優點:非阻塞,不會發生死鎖情況,效率更高
-
缺點:ABA問題(可以通過加入版本號來區分變數是否被修改)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/95069.html
標籤:Java
上一篇:執行緒通訊wait¬ify
下一篇:多執行緒相關概念
