C#開發——ConcurrentDictionary集合

????????ConcurrentDictionary<TKey, TValue> ? 是 C# 中一個專為多線程場景設計的線程安全字典集合,位于 ? System.Collections.Concurrent ? 命名空間中。它允許多個線程同時對字典進行讀寫操作,而無需額外的同步措施。

一、集合特征

此集合有如下特征:

1. 線程安全:

? ? ConcurrentDictionary ? 內部使用了細粒度的鎖定機制(如分段鎖)或無鎖技術,確保在多線程環境中的操作安全。

? 絕大多數操作(如 ? TryAdd ?、 ?TryUpdate ?、 ?TryRemove ?)都是線程安全的。

2. 高性能:

? 由于采用了細粒度鎖定或無鎖技術, ?ConcurrentDictionary ? 在高并發場景下通常比普通字典(如 ? Dictionary<TKey, TValue> ?)具有更好的性能。

3. 靈活的操作方法:

? 提供了多種線程安全的方法,如 ? TryAdd ?、 ?TryUpdate ?、 ?TryRemove ? 和 ? GetOrAdd ? 等。這些方法在操作失敗時不會拋出異常,而是返回一個布爾值來指示操作是否成功。

? 特別需要注意的是, ?AddOrUpdate ? 和 ? GetOrAdd ? 方法中涉及委托的部分并不是完全原子性的,需要開發者特別注意。

4. 允許空值:? 與普通 ? Dictionary ? 不同, ?ConcurrentDictionary ? 允許鍵或值為 ? null ?。

????????使用示例以下是一個簡單的 ? ConcurrentDictionary ? 使用示例:

using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;class Program
{static void Main(){// 創建一個線程安全的 ConcurrentDictionary 實例ConcurrentDictionary<int, string> concurrentDictionary = new ConcurrentDictionary<int, string>();// 使用 TryAdd 方法添加鍵值對concurrentDictionary.TryAdd(1, "one");concurrentDictionary.TryAdd(2, "two");// 使用 TryGetValue 方法獲取值if (concurrentDictionary.TryGetValue(1, out string value)){Console.WriteLine($"Value for key 1: {value}");}// 使用 AddOrUpdate 方法更新或添加鍵值對concurrentDictionary.AddOrUpdate(1, "new one", (key, oldValue) => "updated one");// 使用 TryRemove 方法移除鍵值對concurrentDictionary.TryRemove(2, out _);// 在多線程環境中操作 ConcurrentDictionaryParallel.For(3, 10, i =>{concurrentDictionary.TryAdd(i, i.ToString());});// 遍歷并輸出 ConcurrentDictionary 中的所有元素foreach (var item in concurrentDictionary){Console.WriteLine($"Key: {item.Key}, Value: {item.Value}");}}
}

二、適用場景

? 多線程數據共享:當多個線程需要同時訪問和修改同一個字典時, ?ConcurrentDictionary ? 是最合適的選擇。

? 高并發場景:在需要高性能并發訪問的場景中, ?ConcurrentDictionary ? 的細粒度鎖定機制可以顯著減少鎖競爭。注意事項? 委托方法的線程安全性: ?AddOrUpdate ? 和 ? GetOrAdd ? 方法中涉及委托的部分并不是完全原子性的,因此需要開發者確保委托操作的線程安全性。

? 性能優化:雖然 ? ConcurrentDictionary ? 本身性能較高,但在極端高并發場景下,仍需根據實際需求進行性能測試和優化。

總之, ?ConcurrentDictionary ? 是一個強大的線程安全字典集合,適用于多線程和高并發場景,能夠有效解決普通字典在多線程環境下的線程安全問題。

三、高性能

? ConcurrentDictionary<TKey, TValue> ? 的高性能主要體現在以下幾個方面:

1. 細粒度鎖定與無鎖算法?

????????ConcurrentDictionary ? 內部采用了細粒度鎖定(分段鎖)或無鎖算法(Lock-free),這使得多個線程可以同時對字典進行操作,而不會出現嚴重的競爭條件。例如,它使用了 CAS(Compare and Swap)操作來確保線程安全,這種無鎖機制減少了線程間的同步開銷。

2. 動態擴容

????????ConcurrentDictionary ? 支持動態擴容,能夠根據實際負載自動調整內部數據結構的大小。這種動態調整能力使得它能夠適應不同的并發場景,避免因固定容量導致的性能瓶頸。

3. 高效的哈希表實現

????????ConcurrentDictionary ? 內部基于哈希表實現,使用散列函數將鍵映射到存儲位置,并通過鏈表或紅黑樹處理沖突。這種數據結構支持常數時間復雜度(O(1))的添加、查找和修改操作,從而提高了整體性能。

4. 適用于多生產者和多消費者場景

????????ConcurrentDictionary ? 的設計目標是在多生產者和多消費者環境中提供高效的并發訪問。它允許多個線程同時對字典進行讀寫操作,而無需額外的同步機制。

5. 減少鎖的開銷

????????與傳統的線程安全集合(如通過 ? lock ? 實現的同步機制)相比, ?ConcurrentDictionary ? 通過優化的并發算法減少了鎖的使用頻率和范圍。這種設計不僅提高了性能,還降低了死鎖的風險。

6. 靈活的操作方法

????????ConcurrentDictionary ? 提供了多種線程安全的操作方法,如 ? TryAdd ?、 ?TryUpdate ? 和 ? TryRemove ?,這些方法在操作失敗時不會拋出異常,而是返回布爾值,從而避免了異常處理的開銷。

????????總結 ?ConcurrentDictionary ? 的高性能主要得益于其細粒度鎖定或無鎖算法、動態擴容能力、高效的哈希表實現以及對多生產者和多消費者場景的優化。這些特性使其在高并發場景下表現出色,能夠顯著提高多線程應用程序的性能。

四、常用屬性

Count:獲取字典中鍵值對的數量。

IsEmpty:判斷字典是否為空。

Keys:獲取字典中所有鍵的集合(返回 ? IEnumerable<TKey> ?)。

Values:獲取字典中所有值的集合(返回 ? IEnumerable<TValue> ?)。

實例代碼:

var dict = new ConcurrentDictionary<int, string>();
dict.TryAdd(1, "one");
dict.TryAdd(2, "two");
//Count 屬性
Console.WriteLine(dict.Count); // 輸出:2var dict = new ConcurrentDictionary<int, string>();
//IsEmpty 屬性
Console.WriteLine(dict.IsEmpty); // 輸出:True
dict.TryAdd(1, "one");
Console.WriteLine(dict.IsEmpty); // 輸出:Falsevar dict = new ConcurrentDictionary<int, string>
{{1, "one"},{2, "two"}
};
//Keys 屬性
foreach (var key in dict.Keys)
{Console.WriteLine(key); // 輸出:1, 2
}var dict = new ConcurrentDictionary<int, string>
{{1, "one"},{2, "two"}
};
//Values 屬性
foreach (var value in dict.Values)
{Console.WriteLine(value); // 輸出:"one", "two"
}var dict = new ConcurrentDictionary<int, string>();
bool added = dict.TryAdd(1, "one");
Console.WriteLine(added); // 輸出:True
added = dict.TryAdd(1, "one");
Console.WriteLine(added); // 輸出:False

五、常用方法

TryAdd(TKey key, TValue value):嘗試將鍵值對添加到字典中。如果鍵已存在,則返回 ? false ?。

TryUpdate(TKey key, TValue newValue, TValue comparisonValue):嘗試更新指定鍵的值。只有當當前值等于 ? comparisonValue ? 時,才會更新為 ? newValue 。

TryRemove(TKey key, out TValue value):嘗試從字典中移除指定鍵的鍵值對,并返回其值。

?GetOrAdd(TKey key, TValue value):如果字典中不存在指定鍵,則添加鍵值對并返回值;如果已存在,則返回已有的值。

GetOrAdd(TKey key, Func<TKey, TValue> valueFactory):如果字典中不存在指定鍵,則通過 ? valueFactory ? 動態生成值并添加到字典中。

AddOrUpdate(TKey key, TValue addValue, Func<TKey, TValue, TValue> updateValueFactory):如果鍵不存在,則添加 ? addValue ?;如果鍵已存在,則通過 ? updateValueFactory ? 更新值。

ContainsKey(TKey key):判斷字典中是否包含指定鍵。

Clear():清空字典中的所有鍵值對。

參考代碼:

var dict = new ConcurrentDictionary<int, string>();
//TryAdd()方法
bool added = dict.TryAdd(1, "one");
Console.WriteLine(added); // 輸出:True
added = dict.TryAdd(1, "one");
Console.WriteLine(added); // 輸出:Falsevar dict = new ConcurrentDictionary<int, string>
{{1, "one"}
};
//TryUpdate()方法
bool updated = dict.TryUpdate(1, "new one", "one");
Console.WriteLine(updated); // 輸出:True
updated = dict.TryUpdate(1, "updated one", "old one");
Console.WriteLine(updated); // 輸出:Falsevar dict = new ConcurrentDictionary<int, string>
{{1, "one"}
};
//TryRemove()方法
bool removed = dict.TryRemove(1, out string value);
Console.WriteLine(removed); // 輸出:True
Console.WriteLine(value); // 輸出:"one"var dict = new ConcurrentDictionary<int, string>();
//GetOrAdd()方法
string value = dict.GetOrAdd(1, "one");
Console.WriteLine(value); // 輸出:"one"
value = dict.GetOrAdd(1, "new one");
Console.WriteLine(value); // 輸出:"one"(未更新)var dict = new ConcurrentDictionary<int, string>();
//GetOrAdd()方法
string value = dict.GetOrAdd(1, key => $"Value for {key}");
Console.WriteLine(value); // 輸出:"Value for 1"var dict = new ConcurrentDictionary<int, string>();
//AddOrUpdate()方法
dict.AddOrUpdate(1, "one", (key, oldValue) => $"Updated {oldValue}");
Console.WriteLine(dict[1]); // 輸出:"one"
dict.AddOrUpdate(1, "new one", (key, oldValue) => $"Updated {oldValue}");
Console.WriteLine(dict[1]); // 輸出:"Updated one"var dict = new ConcurrentDictionary<int, string>
{{1, "one"}
};
//ContainsKey()方法
bool contains = dict.ContainsKey(1);
Console.WriteLine(contains); // 輸出:Truevar dict = new ConcurrentDictionary<int, string>
{{1, "one"}
};
//Clear()方法
dict.Clear();
Console.WriteLine(dict.Count); // 輸出:0

其他方法

GetEnumerator():返回一個枚舉器,用于遍歷字典中的鍵值對。

ToDictionary():將ConcurrentDictionary轉換為普通的Dictionary<TKey, TValue>。

總結

ConcurrentDictionary<TKey, TValue> 提供了豐富的線程安全方法,適用于多線程環境。常用的方法如 ? TryAdd、TryUpdate、TryRemove、GetOrAdd和AddOrUpdate等,能夠靈活地處理并發操作,同時避免了傳統字典在多線程場景下的線程安全問題。

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

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

相關文章

Unity百游修煉(2)——Brick_Breaker詳細制作全流程

一、項目簡介 Brick Breaker 是一款經典的打磚塊游戲&#xff0c;本次案例將使用 Unity 引擎來實現該游戲的核心功能。 游戲畫面如下&#xff1a; Brick_ breaker 二、項目結構概覽和前期準備 &#xff08;1&#xff09;在 Unity 項目視圖中&#xff0c;我們可以看到幾個重要…

KubeSphere平臺安裝

KubeSphere簡介 KubeSphere 是一款功能強大的容器管理平臺&#xff0c;以下是其簡介&#xff1a; 1&#xff09;基本信息 開源項目&#xff1a;基于 Apache-2.0 授權協議開源&#xff0c;由 Google Go、Groovy、HTML/CSS 和 Shell 等多種編程語言開發。基礎架構&#xff1a;…

UE5銷毀Actor,移動Actor,簡單的空氣墻的制作

1.銷毀Actor 1.Actor中存在Destory()函數和Destoryed()函數 Destory()函數是成員函數&#xff0c;它會立即標記 Actor 為銷毀狀態&#xff0c;并且會從場景中移除該 Actor。它會觸發生命周期中的銷毀過程&#xff0c;調用 Destroy() 后&#xff0c;Actor 立即進入銷毀過程。具體…

Hadoop 基礎原理

Hadoop 基礎原理 基本介紹Hadoop 的必要性Hadoop 核心組件Hadoop 生態系統中的附加組件 HDFSHDFS 集群架構HDFS 讀寫流程HDFS 寫流程HDFS 讀流程 NameNode 持久化機制 MapReduce底層原理示例 Hadoop 是一個由 Apache 基金會開發的分布式系統基礎架構&#xff0c;主要解決海量數…

Linux編輯器

1.三種模式 2.圖例 3.wq 4.光標的使用

2.24DFS和BFS刷題

洛谷P2895&#xff1a;用BFS走出危險區域&#xff0c;危險區域存在時間&#xff0c;我們用ma記錄最快變成危險區域的時間&#xff0c; 然后每次枚舉時間1然后跟ma數組比較看能不能走&#xff0c;然后時間復雜度為O(305^2)。 #include<iostream> #include<cstring>…

TMDS視頻編解碼算法

因為使用的是DDR進行傳輸&#xff0c;即雙倍頻率采樣&#xff0c;故時鐘只用是并行數據數據的5倍&#xff0c;而不是10倍。 TMDS算法流程&#xff1a; 視頻編碼TMDS算法流程實現&#xff1a; timescale 1 ps / 1ps //DVI編碼通常用于視頻傳輸&#xff0c;將并行數據轉換為適合…

C++中tuple的用法

C中tuple的用法 在C中&#xff0c;std::tuple 是一個模板類&#xff0c;用于存儲一組不同類型的值。它類似于 Python 中的元組&#xff0c;但具有更強大的功能&#xff0c;例如支持不同類型的元素和更復雜的操作。std::tuple 是 C11 標準引入的&#xff0c;位于 <tuple>…

計算機網絡————(一)HTTP講解

基礎內容分類 從TCP/IP協議棧為依托&#xff0c;由上至下、從應用層到基礎設施介紹協議。 1.應用層&#xff1a; HTTP/1.1 Websocket HTTP/2.0 2.應用層的安全基礎設施 LTS/SSL 3.傳輸層 TCP 4.網絡層及數據鏈路層 IP層和以太網 HTTP協議 網絡頁面形成基本 流程&#xff1a…

【網絡編程】廣播和組播

數據包發送方式只有一個接受方&#xff0c;稱為單播。如果同時發給局域網中的所有主機&#xff0c;稱為廣播。只有用戶數據報(使用UDP協議)套接字才能廣播&#xff1a; 廣播地址以192.168.1.0 (255.255.255.0) 網段為例&#xff0c;最大的主機地址192.168.1.255代表該網段的廣…

小程序如何實現跨頁面通信

前言 最近有很多同學問&#xff0c;小程序里面如何進行跨頁面通信。看了下之前的老代碼&#xff0c;基本都是基于onShow或者localStorage。雖然可以實現&#xff0c;但是并不怎么優雅。 今天就來聊一聊&#xff0c;小程序的跨頁面通信的幾種實現方案。或許會有你想要的方案&a…

【工具】win-畫圖 保留圖片信息并僅改變圖片比例的工具

Windows 系統自帶的“畫圖”工具 Windows 系統自帶的“畫圖”&#xff08;Paint&#xff09;工具可以進行簡單的圖片編輯&#xff0c;包括調整圖片大小和比例。 使用方法&#xff1a; 打開“畫圖”工具&#xff08;可以通過在開始菜單中搜索“畫圖”或“Paint”&#xff09;。…

如何編輯autodl中以.bashrc結尾的隱藏文件

在nnunet的運行過程中遇到了設置環境變量的問題。之前沒有接觸過linux系統&#xff0c;但是autodl里面默認是linux系統。.bashrc 是一個在 Bash shell 啟動時執行的腳本文件&#xff0c;常用于設置環境變量、定義別名、加載函數等&#xff0c;用戶可以通過編輯這個文件來定制自…

實驗3 知識表示與推理

實驗3 知識表示與推理 一、實驗目的 &#xff08;1&#xff09;掌握知識和知識表示的基本概念&#xff0c;理解其在AI中的深刻含義與意義&#xff1b; &#xff08;2&#xff09;熟悉AI中常用的知識表示方法的優缺點及其應用場景&#xff1b; &#xff08;3&#xff09;掌握產…

在 M1 Mac 上解鎖 TensorFlow GPU 加速:從環境搭建到實戰驗證

在 M1 Mac 上解鎖 TensorFlow GPU 加速&#xff1a;從環境搭建到實戰驗證 前言&#xff1a;蘋果芯片的深度學習新紀元 隨著 Apple Silicon 芯片的普及&#xff0c;M1/M2/M3 系列 Mac 已成為移動端深度學習開發的新選擇。本文將以 TensorFlow 2.x 為例&#xff0c;手把手教你如…

Python 數據分析概述 ①

一文讀懂Python數據分析&#xff1a;從基礎到實踐全攻略 在當今數字化浪潮中&#xff0c;數據分析已然成為解鎖海量數據價值的關鍵鑰匙&#xff0c;而Python憑借其獨特優勢&#xff0c;在數據分析領域大放異彩。今天&#xff0c;咱們就結合教學PPT內容&#xff0c;深入探索Pyt…

【Gin-Web】Bluebell社區項目梳理6:限流策略-漏桶與令牌桶

本文目錄 一、限流二、漏桶三、令牌桶算法四、Gin框架中實現令牌桶限流 一、限流 限流又稱為流量控制&#xff0c;也就是流控&#xff0c;通常是指限制到達系統的并發請求數。 限流雖然會影響部分用戶的使用體驗&#xff0c;但是能一定程度上保證系統的穩定性&#xff0c;不至…

Linux高并發服務器開發 第十九天(線程 進程)

目錄 1.進程組和會話 2.守護進程 2.1守護進程daemon概念 2.2創建守護進程 3.線程 3.1線程的概念 3.2線程內核三級映射 3.3線程共享 3.4線程優缺點 4.線程控制原語 4.1獲取線程id 4.2創建線程 4.3循環創建N個子線 4.4子線程傳參地址&#xff0c;錯誤示例 4.5線程…

軟件工程和系統分析與設計

軟件工程 1、軟件危機 2、軟件過程模型 2.1 瀑布模型 2.2原型模型 2.3螺旋模型 2.4敏捷模型 2.5軟件統一過程 3、軟件能力成熟度模型 CMM 4、軟件能力成熟度模型集成 CMMI 系統分析與設計 1、結構化方法SASD 1.1結構化分析 DFD 1.2結構化設計 SD-是一種面向數據流的設計…

Qt/C++面試【速通筆記一】

Qt 信號與槽機制 什么是信號&#xff08;Signal&#xff09;和槽&#xff08;Slot&#xff09;&#xff1f; 在Qt中&#xff0c;信號&#xff08;Signal&#xff09;和槽&#xff08;Slot&#xff09;是實現對象之間通信的一種機制。信號是對象在某些事件發生時發出的通知&…