Java 併發基礎知識 原子類的 AtomicMarkableReference 已完全解析

Mondo 科技 更新 2024-03-05

優質作者名單

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"和標記falsecompareandset如果當前值等於"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,則更新為newreferencenewmark,此方法可能會更頻繁地失敗並需要迴圈重試,但它對系統其餘部分的干擾較小。 boolean compareandset(v expectreference, v newreference, boolean expectedmark, boolean newmark)如果當前引用等於expectreference當前標籤等於expectedmark,則更新為newreferencenewmark,提供強大的一致性保證。 boolean attemptmark(v expectedreference, boolean newmark)如果當前基準電壓源等於expectedreference,標記在原子上設定為newmark。這些方法提供對標記引用的原子操作,這些引用可以在多執行緒環境中安全地使用compareandset方法是此類中最常用的方法之一,因為它提供了一種以執行緒安全方式更新引用的方法,僅當引用和標記的當前值與預期值匹配時。

注意:set方法可以設定新的引用和標記,但它不提供原子性保證,如果在設定引用和標記時需要保持它們的原子性,則應使用這些方法compareandsetweakcompareandset方法。

J**A 併發基礎:原子類的 AtomicMarkableReference 綜合分析 - Programmer Goodatomicmarkablereference該類的優點是可以保證多執行緒環境下引用和標籤的原子性更新,有效避免競爭條件,提高程式的併發安全性,使用起來相對簡單直觀compareandset等方法可以輕鬆實現基於舊值的條件更新。

它比普通的原子引用占用更多的空間,因為它需要儲存乙個額外的標籤,這在高併發方案中可能會產生效能開銷,因為需要同時更新引用和標籤。

當您需要在併發環境中維護引用並根據條件(由標記表示)以原子方式更新它時,建議這樣做。atomicmarkablereference但是,在效能要求極高或對記憶體使用情況敏感的情況下,可能需要權衡使用其他同步機制或資料結構的開銷和收益。

跟著我,每天學習網際網絡程式設計技術——程式設計師古德結束!end!end!

相關問題答案

    Java 併發基礎知識 CyclicBarrier 分析!

    優質作者名單 J A 併發基礎 CyclicBarrier 的綜合分析!CyclicBarrier 的優勢在於實現了執行緒之間的相互等待和協作,保證了所有執行緒只有在到達預定的障礙點後才能繼續執行,它支援障礙的復用,非常適合多輪次任務同步,此外,CyclicBarrier 還允許在障礙點執行特定的操...

    Java 併發基礎知識 CountDownLatch 全面分析!

    優質作者名單 j a 併發基礎知識 CountDownLatch 完整分析!程式設計師古德countdownlatch優點是可以簡潔高效地協調多個執行緒的執行順序,保證只有一組執行緒完成後才會觸發其他執行緒的執行,適用於資源載入 任務初始化等場景。它提供了清晰的等待通知機制,易於理解和使用,是提高多...

    Java 併發基礎知識 LinkedBlockingQueue 完整分析!

    優質作者名單 J A 併發基礎知識 LinkedBlockingDeque 完整分析!程式設計師古德linkedblockingqueue類是具有鍊表結構的高效執行緒安全佇列,具有出色的併發效能 靈活的阻塞和非阻塞操作,以及與生產者和消費者模式一起工作的能力linkedblockingqueue它還...

    Java 併發基礎知識 LinkedBlockingDeque 全面分析!

    優質作者名單 J A 併發基礎知識 LinkedBlockingDeque 完整分析!程式設計師古德linkedblockingdeque它提供了雙端佇列的執行緒安全實現,支援佇列兩端的高效插入和刪除操作,並具有可以很好地協調生產者和消費者之間速度差異的阻塞功能,其內部鍊表結構使得出色的併發效能,非...

    Java 併發基礎知識 PriorityBlockingQueue 已完全解決!

    優質作者名單 J A 併發基礎知識 PriorityBlockingQueue 已完全解析!程式設計師古德priorityblockingqueue同時,作為blockingqueue介面的實現,它提供了執行緒安全佇列操作,適用於多執行緒環境下的任務排程和資源管理,簡潔而強大的API使開發者可以輕鬆...