優質作者名單
J**A 併發基礎:原子類的 AtomicMarkableReference 綜合分析 - Programmer Goodatomicmarkablereference
類可以保證引用和布林標誌的原子性更新,有效避免多執行緒環境中的競爭條件,並提供輕鬆實現基於條件的原子性操作的方法,提高程式的併發安全性和可靠性。
atomicmarkablereference
類將布林標記與引用相關聯,並且可以以原子方式更新該對,因此在多執行緒環境中,您可以確保標記和引用的更新是不可分割的操作,而不會被其他執行緒觀察到中間狀態。
模擬乙個業務場景,假設有乙個**購物平台,其中有乙個非常重要的業務就是庫存管理,在這個系統中,每個商品都有乙個庫存數量,當庫存數量為零時,產品就無法再被購買,但是,由於系統是高併發的,可能會有多個執行緒(可能是多個使用者同時發起乙個購買請求)同時嘗試減少同一產品的庫存。
在這種情況下,可以使用它atomicmarkablereference
為了解決這個問題,你可以將庫存數量封裝在乙個物件中並使用它atomicmarkablereference
要引用此物件,可以使用標記位來指示庫存數量是否已被另乙個執行緒“鎖定”以減少。
當乙個執行緒試圖減少庫存時,會先檢查標記位,如果標記位指示庫存未鎖定,則執行緒會嘗試將標記位原子設定為“鎖定”狀態,並獲取當前庫存數量,如果成功,執行緒可以安全地減少庫存,而不必擔心其他執行緒同時修改它, 減少庫存後,執行緒將原子清除標記位,表示庫存現在可以被其他執行緒鎖定和修改。
如果鎖定清單的嘗試失敗(因為另乙個執行緒已鎖定清單),則該執行緒可以選擇重試、等待或使用該執行緒向使用者返回錯誤訊息atomicmarkablereference
在高併發環境下保證庫存數量的正確性和一致性,避免超賣。
atomicmarkablereference
類主要用於解決併發環境中的資料一致性問題,特別是當需要以原子方式更新引用及其關聯狀態(通常由布林標記表示)時,並且通常可用於解決類似於以下內容的問題:
無鎖資料結構:在實現無鎖(lock-free
) 或基於樂觀鎖 (optimistic locking
) 資料結構atomicmarkablereference
它可用於以原子方式更新節點的引用和狀態。 狀態跟蹤:當您需要跟蹤物件的狀態時可以使用atomicmarkablereference
。例如,可能有乙個物件需要跨多個執行緒共享,您需要通過在其中儲存物件和標記(表示處理狀態)來了解該物件是否已經處理atomicmarkablereference
在檢查和處理物件時,可以確保操作的原子性。 快取一致性:構建快取系統時atomicmarkablereference
這可用於確保快取的條目以原子方式更新,例如,當快取的條目需要失效或更新時,可以使用標記來指示條目的有效性並使用atomicmarkablereference
以原子方式更新條目和標籤。 避免 ABA 問題:使用基於比較和交換 (compare-and-swap, cas
當你操作原子類時,你可能會遇到所謂的 ABA 問題,這意味著乙個變數的原始值為 a,然後另乙個執行緒將其更改為 b,然後又將其更改回 a,因此用 cas 檢查此變數的執行緒會發現它的值沒有更改, 但實際上它已經被其他執行緒修改了。atomicmarkablereference
通過引入額外的標記位可以避免此問題,因為標記位的變化可用於檢測中間的狀態變化,即使引用的值沒有變化。 下面是乙個簡單的 j**a**,演示了如何使用它atomicmarkablereference
類:
import j**a.util.concurrent.atomic.atomicmarkablereference;
public class atomicmarkablereferencedemo
在上面的**中,首先建立了乙個atomicmarkablereference
例項,預設值為字串"hello"和標記false
用compareandset
如果當前值等於"hello"並標記為false
,則更新為"world"跟true
,該值返回乙個布林值,該值指示引用和標記是否已成功更新,然後再次使用compareandset
該方法嘗試根據不同的舊值和標記進行更新,但這次更新失敗,因為當前值或標記與預期不匹配,最後,再次獲取並列印當前值和標記,以確認它們沒有失敗,因為它們失敗了compareandset
打電話和改變。
atomicmarkablereference
實現原理主要依靠底層硬體支援,尤其是原子性(compare-and-swap, cas
) 操作。Cas 操作是一種無鎖演算法,允許多個執行緒在不使用鎖的情況下安全地操作共享資料。
在atomicmarkablereference
,CAS 操作用於確保引用和標記的同時更新是原子的,特別是atomicmarkablereference
內部維護兩個字段:乙個是引用物件,另乙個是布林標籤,兩個欄位的更新都是原子的,這是通過 cas 操作實現的。
但atomicmarkablereference
事實上,它不是使用單個 cas 操作來更新引用和標記,而是使用兩個單獨的 cas 操作,並且兩個操作之間需要有某種方式來確保原子性,這通常是通過在內部使用迴圈來實現的,該迴圈一直持續到引用和標記都成功更新為止, 或直到確定更新不太可能成功。
為了保證原子性,atomicmarkablereference
採用一種稱為“雙 cas”或“雙重檢查鎖定”的技術,它包括兩個步驟:首先檢查引用和標籤的當前值是否與預期值匹配,如果匹配,則執行 CAS 操作以嘗試更新它們,如果在此過程中,任一值發生變化(由於其他執行緒的併發修改), 然後更新失敗,需要重試。
底層演算法的核心是兩個 CAS 操作:乙個用於更新參考,另乙個用於更新標記,這兩個操作都需要滿足某些條件才能成功。 嘗試更新引用時,需要確保當前標記值與預期的標記值匹配; 同樣,在嘗試更新標籤時,您需要確保當前引用值與預期的引用值匹配。
然而,這兩個 cas 操作並不是完全獨立的,它們被組合在一起,以確保在引用和標記的更新之間不會發生其他執行緒的干擾,這通常是通過在內部使用乙個迴圈來實現的,該迴圈嘗試更新引用和標記,直到它成功或確定它不能成功(例如, 由於其他執行緒的併發修改,不再滿足條件)。
總結:atomicmarkablereference
類,利用底層CAS 操作以及乙個一種稱為“雙 CAS”或“雙檢查鎖定”的技術。在併發環境中實現對引用和標記的原子更新。 然而,重要的是要注意,並非所有方法都是原子的(例如set
方法),使用時需要特別小心,以確保螺紋安全。
在這裡:atomicmarkablereference
類中主要方法的含義:
atomicmarkablereference(v initialref, boolean initialmark)
建構函式,用於建立乙個新的建構函式atomicmarkablereference
例項,設定初始引用值和標籤。 v getreference()
獲取當前引用的物件。 boolean ismarked()
獲取當前標記的值。 void set(v newreference, boolean newmark)
設定新的參考值和標籤,注意此方法不是原子的; 它首先設定引用,然後設定標誌,如果需要原子性,則應使用該標誌compareandset
方法。 boolean weakcompareandset(v expectreference, v newreference, boolean expectedmark, boolean newmark)
以原子方式設定引用和標記的值,但如果當前引用等於expectreference
當前標籤等於expectedmark
,則更新為newreference
跟newmark
,此方法可能會更頻繁地失敗並需要迴圈重試,但它對系統其餘部分的干擾較小。 boolean compareandset(v expectreference, v newreference, boolean expectedmark, boolean newmark)
如果當前引用等於expectreference
當前標籤等於expectedmark
,則更新為newreference
跟newmark
,提供強大的一致性保證。 boolean attemptmark(v expectedreference, boolean newmark)
如果當前基準電壓源等於expectedreference
,標記在原子上設定為newmark
。這些方法提供對標記引用的原子操作,這些引用可以在多執行緒環境中安全地使用compareandset
方法是此類中最常用的方法之一,因為它提供了一種以執行緒安全方式更新引用的方法,僅當引用和標記的當前值與預期值匹配時。
注意:set
方法可以設定新的引用和標記,但它不提供原子性保證,如果在設定引用和標記時需要保持它們的原子性,則應使用這些方法compareandset
或weakcompareandset
方法。
J**A 併發基礎:原子類的 AtomicMarkableReference 綜合分析 - Programmer Goodatomicmarkablereference
該類的優點是可以保證多執行緒環境下引用和標籤的原子性更新,有效避免競爭條件,提高程式的併發安全性,使用起來相對簡單直觀compareandset
等方法可以輕鬆實現基於舊值的條件更新。
它比普通的原子引用占用更多的空間,因為它需要儲存乙個額外的標籤,這在高併發方案中可能會產生效能開銷,因為需要同時更新引用和標籤。
當您需要在併發環境中維護引用並根據條件(由標記表示)以原子方式更新它時,建議這樣做。atomicmarkablereference
但是,在效能要求極高或對記憶體使用情況敏感的情況下,可能需要權衡使用其他同步機制或資料結構的開銷和收益。
跟著我,每天學習網際網絡程式設計技術——程式設計師古德結束!end!end!