C#vb.net中Interlocked類實現原子操作加減計算,涵蓋狀態切換、計數控制等常見場景

以下是 C# 中使用?int?類型結合?Interlocked?類實現原子操作的完整示例,涵蓋狀態切換、計數控制等常見場景:

完整代碼示例csharp

using System;
using System.Threading;/// <summary>
/// 基于整數類型的原子操作工具類(線程安全)
/// 適用于開關狀態控制、計數器等場景
/// </summary>
public static class AtomicStateManager
{// 核心狀態變量:用整數表示不同狀態// 示例場景:0=關閉(False),1=開啟(True);也可擴展為多狀態(如0=未初始化,1=運行中,2=已停止)private static int _state = 0; #region 基礎狀態控制(開關場景)/// <summary>/// 原子設置狀態為“開啟”(對應值1)/// </summary>public static void Enable(){// 直接將狀態設為1,無視當前值(原子操作)Interlocked.Exchange(ref _state, 1);}/// <summary>/// 原子設置狀態為“關閉”(對應值0)/// </summary>public static void Disable(){// 直接將狀態設為0,無視當前值(原子操作)Interlocked.Exchange(ref _state, 0);}/// <summary>/// 原子切換狀態(0→1 或 1→0)/// </summary>public static void Toggle(){// 循環嘗試切換,直到成功(處理并發沖突)do{int currentState = _state; // 讀取當前狀態int newState = currentState == 1 ? 0 : 1; // 計算目標狀態// 比較并交換:如果當前值仍為currentState,則更新為newState// 若交換失敗(返回值≠currentState),則重試} while (Interlocked.CompareExchange(ref _state, newState, _state) != _state);}/// <summary>/// 原子讀取當前狀態是否為“開啟”/// </summary>/// <returns>True=開啟(1),False=關閉(0)</returns>public static bool IsEnabled(){// 用CompareExchange確保讀取到最新值(避免CPU緩存導致的臟讀)return Interlocked.CompareExchange(ref _state, 0, 0) == 1;}#endregion#region 計數器場景(原子增減)/// <summary>/// 原子遞增狀態值(+1)/// </summary>/// <returns>遞增后的新值</returns>public static int Increment(){return Interlocked.Increment(ref _state);}/// <summary>/// 原子遞減狀態值(-1)/// </summary>/// <returns>遞減后的新值</returns>public static int Decrement(){return Interlocked.Decrement(ref _state);}/// <summary>/// 原子讀取當前計數值/// </summary>/// <returns>當前狀態值</returns>public static int GetCount(){return Interlocked.CompareExchange(ref _state, 0, 0);}#endregion#region 高級場景:條件更新(僅當滿足條件時修改)/// <summary>/// 僅當當前狀態為“關閉”時,原子設置為“開啟”/// </summary>/// <returns>True=更新成功,False=當前狀態不滿足條件</returns>public static bool EnableIfDisabled(){// 比較并交換:若當前值為0(關閉),則更新為1(開啟)int originalValue = Interlocked.CompareExchange(ref _state, 1, 0);return originalValue == 0; // 若原始值為0,說明更新成功}/// <summary>/// 僅當當前狀態為目標值時,原子更新為新值/// </summary>/// <param name="expectedValue">預期當前值</param>/// <param name="newValue">目標新值</param>/// <returns>True=更新成功,False=當前值不符預期</returns>public static bool UpdateIfMatch(int expectedValue, int newValue){int originalValue = Interlocked.CompareExchange(ref _state, newValue, expectedValue);return originalValue == expectedValue;}#endregion
}

使用示例csharp

class Program
{static void Main(){// 1. 開關狀態場景AtomicStateManager.Enable();Console.WriteLine($"是否開啟:{AtomicStateManager.IsEnabled()}"); // 輸出:TrueAtomicStateManager.Toggle();Console.WriteLine($"切換后是否開啟:{AtomicStateManager.IsEnabled()}"); // 輸出:Falsebool updateSuccess = AtomicStateManager.EnableIfDisabled();Console.WriteLine($"是否成功開啟:{updateSuccess}"); // 輸出:TrueConsole.WriteLine($"當前狀態:{AtomicStateManager.IsEnabled()}"); // 輸出:True// 2. 計數器場景AtomicStateManager.Increment(); // 狀態從1→2AtomicStateManager.Increment(); // 狀態從2→3Console.WriteLine($"當前計數:{AtomicStateManager.GetCount()}"); // 輸出:3AtomicStateManager.Decrement(); // 狀態從3→2Console.WriteLine($"遞減后計數:{AtomicStateManager.GetCount()}"); // 輸出:2// 3. 條件更新場景bool conditionUpdate = AtomicStateManager.UpdateIfMatch(2, 100);Console.WriteLine($"條件更新是否成功:{conditionUpdate}"); // 輸出:TrueConsole.WriteLine($"更新后的值:{AtomicStateManager.GetCount()}"); // 輸出:100}
}

核心原理與優勢

  1. 原子性保證
    Interlocked?類的方法通過底層硬件指令實現原子操作,確保操作過程不會被其他線程打斷,避免競態條件。

  2. 性能優化
    相比?lock?等鎖機制,Interlocked?操作無需上下文切換,開銷更小,適合高頻訪問場景。

  3. 可見性保證
    所有?Interlocked?操作會強制刷新 CPU 緩存,確保所有線程看到的是最新值,避免因緩存導致的數據不一致。

  4. 靈活性擴展
    示例中用?0?和?1?表示開關狀態,實際可擴展為多狀態(如?0=未初始化1=運行中2=已停止),通過?UpdateIfMatch?方法實現復雜狀態轉換。

這種方式特別適合 IIS 等多線程環境下的全局變量控制,可有效避免并發修改導致的異常。


VB.NET的用法例子:

將布爾值轉換為整數類型(如?Integer)后使用?Interlocked?類的原子操作(如遞增、遞減、比較交換),在多線程場景中會更直觀且高效。這種方式特別適合需要 "開關狀態切換" 或 "計數控制" 的場景。

以下是?VB.NET?中基于整數類型的原子操作實現,以?GetServerInfo?的狀態控制為例:

實現示例:VB.NET 用整數類型模擬狀態,結合原子操作

vb

Imports System.Threading' 用整數表示狀態:0=關閉(False),1=開啟(True)
Private Shared _serverInfoState As Integer = 0 ' 初始狀態:關閉' 原子開啟(設置為1)
Public Sub EnableServerInfo()Interlocked.Exchange(_serverInfoState, 1)
End Sub' 原子關閉(設置為0)
Public Sub DisableServerInfo()Interlocked.Exchange(_serverInfoState, 0)
End Sub' 原子切換狀態(0→1 或 1→0)
Public Sub ToggleServerInfo()' 循環嘗試切換,直到成功(處理并發沖突)DoDim currentState = _serverInfoStateDim newState = If(currentState = 1, 0, 1)' 比較并交換:如果當前值仍為 currentState,則更新為 newStateLoop While Interlocked.CompareExchange(_serverInfoState, newState, currentState) <> currentState
End Sub' 原子讀取當前狀態
Public Function IsServerInfoEnabled() As Boolean' 讀取操作本身是原子的,但用 CompareExchange 確保可見性Return Interlocked.CompareExchange(_serverInfoState, 0, 0) = 1
End Function' 原子遞增(適合計數場景)
Public Sub IncrementCounter()Interlocked.Increment(_serverInfoState)
End Sub' 原子遞減(適合計數場景)
Public Sub DecrementCounter()Interlocked.Decrement(_serverInfoState)
End Sub

優勢說明

  1. 操作直觀
    用?0?和?1?對應?False?和?True,通過?Interlocked.Increment/Decrement?可直接實現計數,無需額外轉換邏輯。

  2. 性能優異
    Interlocked?類的方法是底層硬件支持的原子操作,比?SyncLock?等鎖機制開銷更小,尤其適合高頻訪問的場景。

  3. 避免競態條件

    • Exchange?確保 "設置新值" 操作的原子性,不會被其他線程打斷。
    • CompareExchange?結合循環可實現 "檢查 - 更新" 的原子性(如?ToggleServerInfo?方法),避免并發下的狀態不一致。
  4. 可見性保證
    Interlocked?操作會強制刷新 CPU 緩存,確保所有線程看到的是最新值(避免因緩存導致的 "臟讀")。

適用場景

  • 簡單的開關狀態(如?GetServerInfo?的啟用 / 禁用)。
  • 計數器(如統計并發請求數、操作次數)。
  • 需要原子 "檢查并修改" 的邏輯(如僅當狀態為關閉時才開啟)。

如果你的場景涉及更復雜的狀態轉換(如多值狀態),這種整數映射方式同樣適用,只需擴展數值對應的含義即可(如?0=未初始化1=運行中2=已停止)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/93088.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/93088.shtml
英文地址,請注明出處:http://en.pswp.cn/web/93088.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RCL 2025 | LLM采樣機制的新視角:來自處方性偏移的解釋

1. 導讀 大型語言模型&#xff08;Large Language Models, LLMs&#xff09;在自主決策場景中的應用日益廣泛&#xff0c;它們需要在龐大的行動空間中進行響應采樣&#xff08;response sampling&#xff09;。然而&#xff0c;驅動這一采樣過程的啟發式機制仍缺乏深入研究。本…

08 ABP Framework Blazor UI

ABP Framework Blazor UI 架構 overview ABP Blazor UI 系統構建在 Blazorise 組件庫之上&#xff0c;為構建數據驅動應用提供結構化方法&#xff0c;包含 CRUD 操作、主題和本地化的一致模式。 #mermaid-svg-QAvWlELsLhZgYXHu {font-family:"trebuchet ms",verdana,…

JUC學習筆記-----LinkedBlockingQueueConcurrentLinkedQueueCopyOnWriteArrayList

LinkedBlockingQueue基本的入隊出隊初始化public class LinkedBlockingQueue<E> extends AbstractQueue<E>implements BlockingQueue<E>, java.io.Serializable {// 靜態內部類 Node&#xff0c;用于存儲隊列元素及維護節點間關系static class Node<E>…

小杰python高級(six day)——pandas庫

1.數據可視化用于繪制 DataFrame 數據圖形&#xff0c;它允許用戶直接從 DataFrame 創建各種類型的圖表&#xff0c;而不需要使用其他繪圖庫&#xff08;底層實際上使用了 Matplotlib&#xff09;。&#xff08;1&#xff09;plotDataFrame.plot(*args, **kwargs)功能&#xff…

第十六屆藍橋杯青少組C++省賽[2025.8.9]第二部分編程題(1 、慶典隊列)

參考程序&#xff1a;#include <iostream> using namespace std;int main() {int n, A;cin >> n >> A; // 輸入&#xff1a;n 和 A&#xff0c;用空格隔開cout << n / A; // 整數相除&#xff0c;自動向下取整return 0; }

C++進階:智能指針

目錄1. RAII與智能指針2. C庫中的智能指針2.1 智能指針auto_ptr2.2 智能指針unique_ptr2.3 智能指針shared_ptr3. shared_ptr的循環引用4. 智能指針的定值刪除器1. RAII與智能指針 上一篇文章學習了異常相關的知識&#xff0c;其中遺留了一個異常安全相關的問題。那就是異常的拋…

Tkinter 實現按鈕鼠標懸浮提示:兩種方案(繼承Frame與不繼承)

在 Tkinter 桌面應用開發中&#xff0c;為按鈕添加“鼠標懸浮提示”是提升用戶體驗的常用功能——無需點擊&#xff0c;只需將鼠標挪到按鈕上方&#xff0c;就能自動顯示按鈕功能說明。本文將詳細介紹兩種實現方案&#xff1a;不繼承 Frame 類&#xff08;快速簡潔版&#xff0…

20250814 最小生成樹總結

引子 啊啊額&#xff0c;從一張圖里抽出幾條邊&#xff0c;組成一棵樹&#xff0c;無環n?1n-1n?1條邊&#xff0c;就是生成樹。那么邊權和最小的生成樹就叫最小生成樹&#xff0c;最大生成樹同理。 kruskal最小生成樹 要求kruskal最小生成樹&#xff0c;我們首先用結構體數組…

數據大集網:實體店獲客引流的數字化引擎,解鎖精準拓客新密碼?

?在實體店面臨流量焦慮、獲客成本攀升的當下&#xff0c;實體店獲客引流工具的重要性愈發凸顯。如何在激烈的市場競爭中精準觸達目標客戶、構建可持續的客流增長模式&#xff1f;數據大集網憑借其創新的智能獲客體系與全鏈路服務能力&#xff0c;正成為萬千實體店突破增長瓶頸…

nginx --ssl證書生成mkcert

github https://github.com/FiloSottile/mkcert/releases網盤下載地址 https://pan.baidu.com/s/1XI0879pqu7HXZMnmQ9ztaw 提取碼: 1111windows使用示例

守拙以致遠:個人IP的長青之道|創客匠人

2025年被認為是AI應用全面爆發的一年。各種人工智能工具在寫作、制圖、剪輯等領域廣泛使用&#xff0c;大大提升了個人和團隊的工作效率。對于個人IP而言&#xff0c;這類工具的出現確實帶來了新的機會&#xff0c;但也伴隨著一種現象——一些人開始過度依賴甚至神化AI&#xf…

USB 3.0 LTSSM 狀態機

USB2.0在電源供應后&#xff0c;通過Pull Up D-來決定枚舉LS&#xff0c;Pull Up D有一個USB高速握手過程&#xff0c;來決定HS FS。USB3.0則會通過鏈路訓練&#xff08;Link Training&#xff09;&#xff0c;來準備USB3.0通信。每當我們插上USB線的時候&#xff0c;對于3.0的…

MySQL窗口函數與PyMySQL以及SQL注入

MySQL窗口函數與PyMySQL實戰指南&#xff1a;從基礎到安全編程 引言 在數據處理和分析領域&#xff0c;MySQL作為最流行的關系型數據庫之一&#xff0c;其窗口函數功能為數據分析提供了強大的支持。同時&#xff0c;Python作為數據分析的主要語言&#xff0c;通過PyMySQL庫與My…

高級項目——基于FPGA的串行FIR濾波器

給大家安利一個 AI 學習神站&#xff01;在這個 AI 卷成紅海的時代&#xff0c;甭管你是硬核開發者還是代碼小白&#xff0c;啃透 AI 技能樹都是剛需。這站牛逼之處在于&#xff1a;全程用 "變量名式" 幽默 生活化類比拆解 AI&#xff0c;從入門到入土&#xff08;啊…

JPrint免費的Web靜默打印控件:PDF打印中文亂碼異常解決方案

文章目錄JPrint是什么&#xff1f;中文亂碼&#xff08;Using fallback font xxx for xxxx&#xff09;1.字體嵌入2.客戶機字體安裝開源地址相關目錄導航使用文檔端口號修改代理使用場景打印服務切換中文亂碼解決方案 JPrint是什么&#xff1f; JPrint是一個免費開源的可視化靜…

MFT 在零售行業的實踐案例與場景:加速文件集成與業務協作的高效方案

零售行業競爭激烈、數字化轉型迭代迅速&#xff0c;業務對數據與檔案的傳輸、處理和整合要求極高。無論是新品上市市場數據&#xff0c;還是供應鏈物流單據&#xff0c;集成方式不論是通過API或是檔案傳輸, 對于傳輸的穩定性,安全性與性能, 都會直接影響決策效率與顧客體驗。MF…

OSG+Qt —— 筆記1 - Qt窗口加載模型(附源碼)

?? OSG/OsgEarth 相關技術、疑難雜癥文章合集(掌握后可自封大俠 ?_?)(記得收藏,持續更新中…) OSG+Qt所用版本皆為: Vs2017+Qt5.12.4+Osg3.6.5+OsgQt(master) 效果 代碼(需將cow.osg、reflect.rgb拷貝至工程目錄下) OsgForQt.ui main.cpp

開源安全云盤存儲:Hoodik 實現端到端數據加密,Docker快速搭建

以下是對 Hoodik 的簡單介紹&#xff1a; Hoodik 是一個使用 Rust 和 Vue 開發的輕量級自托管安全云存儲解決方案采用了非對稱RSA密鑰對和AES混合加密策略&#xff0c;從文件存儲加密到數據鏈路加密&#xff0c;全程保證數據安全支持Docker一鍵私有部署&#xff0c;數據和服務…

[C++] Git 使用教程(從入門到常用操作)

1. Git 簡介 Git 是一款分布式版本控制系統&#xff0c;用來跟蹤文件變化、協作開發、管理項目版本。 它是開源的&#xff0c;由 Linus Torvalds 在 2005 年開發&#xff0c;廣泛用于開源與企業項目中。 2. 安裝 Git Windows 前往 Git 官網 下載并安裝。 安裝時建議勾選 Git…

實盤回測一體的期貨策略開發:tqsdk獲取歷史數據并回測,附python代碼

原創內容第969篇&#xff0c;專注AGI&#xff0c;AI量化投資、個人成長與財富自由。 星球好多同學希望說說實盤&#xff0c;我們就從實盤開始吧。 我們選擇tqsdk給大家講解&#xff0c;tqsdk支持免費注冊&#xff0c;使用模擬賬戶&#xff0c;歷史和實時數據&#xff0c;方便…