Java的CAS操作

来源:https://www.cnblogs.com/feiyu2/archive/2023/05/21/CAS.html
-Advertisement-
Play Games

CAS 是樂觀鎖設計思想的實現。CAS 的思想是:在“讀取 - 修改 - 寫回”操作序列中,先讀取並修改數據,寫回數據前先判斷讀取數據後的這段時間內數據是否發生變化(共用變數的當前值是否是我們的期望值)。通過 CAS 我們可以以無鎖的方式,保證對共用數據進行 “讀取 - 修改 - 寫回” 操作序列的... ...


介紹 CAS

技術是為瞭解決問題而生的,通過 CAS 我們可以以無鎖的方式,保證對共用數據進行 “讀取 - 修改 - 寫回” 操作序列的正確性。

CAS 是樂觀鎖設計思想的實現。CAS 的思想是:在“讀取 - 修改 - 寫回”操作序列中,先讀取並修改數據,寫回數據前先判斷讀取數據後的這段時間內數據是否發生變化(共用變數的當前值是否是我們的期望值):

  • 如果在此期間數據沒有發生變化(共用資源的當前值是我們的期望值),那麼就把修改後的值寫回
  • 如果在此期間其他的線程修改了數據,數據發生了變化(共用資源的當前值不是我們的期望值),那麼就放棄本次寫回操作,再基於最新的數據進行修改然後重試,避免發生數據更新丟失

CAS 更加底層的實現依賴於 CPU 提供的特定指令,具體根據體繫結構的不同還存在著明顯區別。比如,x86 CPU 提供 cmpxchg 指令;而在精簡指令集的體系架構中,則通常是靠一對指令(如“load and reserve”和“store conditional”)實現的。在大多數處理器上 CAS 都是非常輕量級的操作,這也是其優勢所在。

Java 的 CAS 操作

CAS 依賴於 Unsafe 類提供的一些底層能力,進行底層操作。

/**
 * Atomically update Java variable to x if it is currently
 * holding expected.
 * @return true if successful
 */
public final native boolean compareAndSwapInt(Object o, long offset,
                                              int expected,
                                              int x);

在調用 compareAndSwap() 方法時,我們需要傳入需要修改的共用變數、對象偏移量、我們期望的變數當前值、要寫回的值。如果變數的當前值和我們的期望值相等,則寫回成功,返回 true,否則寫回失敗,返回 false。

Unsafe 類是 Java 提供的一個操作記憶體的非安全類,操作對象和對應的變數來完成 CAS 操作。顯然 Unsafe 類過於底層,調用 Unsafe 類的方法不是大多數應用場景的最好選擇。目前 Java 提供了兩種公共 API,可以實現 CAS 操作:

  • 一種是 Atomic 原子類。Atomic 包中的類對 Unsafe 類進行了封裝,使我們可以更方便的使用 CAS 操作。Atomic 包提供了常見的原子性數據類型,甚至是引用、數組等相關原子類型和原子更新操作工具。
  • 還有一種是 Variable Handle API,它源自於JEP 193,提供了各種粒度的原子或者有序性的操作等。

CAS 的優劣局限

CAS 的優點:在大多數處理器上 CAS 都是非常輕量級的操作。


CAS 的局限:

  • CAS 操作是針對一個共用變數的,如果需要解決多個變數的原子性問題,建議還是使用互斥鎖方案。
  • 存在 ABA 問題:當一個線程在進行 CAS 操作時,另一個線程可能會在此期間修改了同一個共用變數的值,然後又將其改回原來的值。這種情況下,CAS 操作就無法檢測到共用變數值的變化,從而導致 ABA 問題。如果我們僅僅在寫回數據前判斷數值是 A,可能導致不合理的寫回操作。針對這種情況,Java 提供了 AtomicStampedReference 工具類,通過為對象引用建立類似版本號(stamp)的方式,來解決 ABA 問題,保證 CAS 的正確性。
  • 如果有大量的線程同時對一個共用變數進行 CAS 操作,競爭過於激烈的情況下,嘗試進行 CAS 操作的線程只會白白消耗處理器資源,而不會做任何有價值的工作,這就會帶來性能的浪費。

本文來自博客園,作者:真正的飛魚,轉載請註明原文鏈接:https://www.cnblogs.com/feiyu2/p/CAS.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ## 1.自定義starter的作用 在我們的日常開發工作中,經常會有一些獨立於業務之外的配置模塊,比如阿裡雲oss存儲的時候,我們需要一個工具類進行文件上傳。我們經常將其放到一個特定的包下,然後如果另一個工程需要復用這塊功能的時候,需要將代碼硬拷貝到另一個工程,重新集成一遍,這樣會非常麻煩。如果我 ...
  • # 使用 Async Rust 構建簡單的 P2P 節點 ### P2P 簡介 - P2P:peer-to-peer - P2P 是一種網路技術,可以在不同的電腦之間共用各種計算資源,如 CPU、網路帶寬和存儲。 - P2P 是當今用戶線上共用文件(如音樂、圖像和其他數字媒體)的一種非常常用的方法 ...
  • ## 1.1 為什麼要學 Qt Qt是一個跨平臺的 C++ 圖形用戶界面應用程式框架 Qt 為應用程式開發者提供建立藝術級圖形界面所需的所有功能 Qt 是完全面向對象的,很容易擴展,並且允許真正的組件編程 (1)Qt 發展史 在講解學習 Qt 的必要性之前, 先來瞭解下 Qt 的發展歷史: 1991 ...
  • 用go設計開發一個自己的輕量級登錄庫/框架吧(拓展篇),給自己的庫/框架拓展一下吧,主庫:https://github.com/weloe/token-go ...
  • ### 1.0 匿名對象的基本知識 * 匿名對象 顧名思義,匿名對象指的就是沒有名字的對象,在使用中理解為實例化一個類對象,但是並不把它賦給一個對應的類變數,而是直接使用。在理解匿名對象前,我們先創建一個類便於後面的使用。 * 匿名對象具有以下特征: 語法上:只創建對象,但不用變數來接收,例如:假設 ...
  • Groovy是一種基於Java平臺的動態編程語言,它結合了Python、Ruby和Smalltalk等語言的特性,同時與Java無縫集成。 ...
  • 從 JDK7 開始,引入了表示非同步通道的 `AsynchronousSockerChannel` 類和 `AsynchronousServerSocketChannel` 類,這兩個類的作用與 `SocketChannel` 類和 `ServerSockelChannel` 相似,區別在於非同步通道的 ...
  • ## 文章首發 [【重學C++】02 脫離指針陷阱:深入淺出 C++ 智能指針](https://mp.weixin.qq.com/s/McD-kfsiQ7hW1UnsAriC1g) ## 前言 大家好,今天是【重學C++】系列的第二講,我們來聊聊C++的智能指針。 ## 為什麼需要智能指針 在上一 ...
一周排行
    -Advertisement-
    Play Games
  • 一個自定義WPF窗體的解決方案,借鑒了呂毅老師的WPF製作高性能的透明背景的異形視窗一文,併在此基礎上增加了滑鼠穿透的功能。可以使得透明窗體的滑鼠事件穿透到下層,在下層窗體中響應。 ...
  • 在C#中使用RabbitMQ做個簡單的發送郵件小項目 前言 好久沒有做項目了,這次做一個發送郵件的小項目。發郵件是一個比較耗時的操作,之前在我的個人博客裡面回覆評論和友鏈申請是會通過發送郵件來通知對方的,不過當時只是簡單的進行了非同步操作。 那麼這次來使用RabbitMQ去統一發送郵件,我的想法是通過 ...
  • 當你使用Edge等瀏覽器或系統軟體播放媒體時,Windows控制中心就會出現相應的媒體信息以及控制播放的功能,如圖。 SMTC (SystemMediaTransportControls) 是一個Windows App SDK (舊為UWP) 中提供的一個API,用於與系統媒體交互。接入SMTC的好 ...
  • 最近在微軟商店,官方上架了新款Win11風格的WPF版UI框架【WPF Gallery Preview 1.0.0.0】,這款應用引入了前沿的Fluent Design UI設計,為用戶帶來全新的視覺體驗。 ...
  • 1.簡單使用實例 1.1 添加log4net.dll的引用。 在NuGet程式包中搜索log4net並添加,此次我所用版本為2.0.17。如下圖: 1.2 添加配置文件 右鍵項目,添加新建項,搜索選擇應用程式配置文件,命名為log4net.config,步驟如下圖: 1.2.1 log4net.co ...
  • 之前也分享過 Swashbuckle.AspNetCore 的使用,不過版本比較老了,本次演示用的示例版本為 .net core 8.0,從安裝使用開始,到根據命名空間分組顯示,十分的有用 ...
  • 在 Visual Studio 中,至少可以創建三種不同類型的類庫: 類庫(.NET Framework) 類庫(.NET 標準) 類庫 (.NET Core) 雖然第一種是我們多年來一直在使用的,但一直感到困惑的一個主要問題是何時使用 .NET Standard 和 .NET Core 類庫類型。 ...
  • WPF的按鈕提供了Template模板,可以通過修改Template模板中的內容對按鈕的樣式進行自定義。結合資源字典,可以將自定義資源在xaml視窗、自定義控制項或者整個App當中調用 ...
  • 實現了一個支持長短按得按鈕組件,單擊可以觸發Click事件,長按可以觸發LongPressed事件,長按鬆開時觸發LongClick事件。還可以和自定義外觀相結合,實現自定義的按鈕外形。 ...
  • 一、WTM是什麼 WalkingTec.Mvvm框架(簡稱WTM)最早開發與2013年,基於Asp.net MVC3 和 最早的Entity Framework, 當初主要是為瞭解決公司內部開發效率低,代碼風格不統一的問題。2017年9月,將代碼移植到了.Net Core上,併進行了深度優化和重構, ...