欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

.NET?中的線程安全數(shù)據(jù)結(jié)構(gòu)詳解

 更新時間:2024年12月25日 14:07:46   作者:賈光輝  
.NET提供了多種線程安全的數(shù)據(jù)結(jié)構(gòu),適用于不同的場景,本篇將介紹它們的簡單使用以及在.NETCore和.NET Framework中的可用性,感興趣的朋友一起看看吧

在多線程編程中,線程安全的數(shù)據(jù)結(jié)構(gòu)是確保數(shù)據(jù)一致性和避免競爭條件的關(guān)鍵。.NET 提供了多種線程安全的數(shù)據(jù)結(jié)構(gòu),適用于不同的場景,本篇將介紹它們的簡單使用以及在 .NET Core 和 .NET Framework 中的可用性。

1. ConcurrentQueue

ConcurrentQueue 是一個線程安全的先進先出 (FIFO) 隊列。它允許多個線程同時進行入隊和出隊操作,而不會導致數(shù)據(jù)不一致。

適用場景

  • 生產(chǎn)者-消費者模式:多個生產(chǎn)者線程將數(shù)據(jù)項添加到隊列中,多個消費者線程從隊列中取出數(shù)據(jù)項進行處理
  • 任務調(diào)度:將任務添加到隊列中,由工作線程從隊列中取出任務并執(zhí)行

優(yōu)點

  • 高效的并發(fā)操作:支持多個線程同時進行入隊和出隊操作
  • 無鎖設計:內(nèi)部使用無鎖算法,避免了鎖競爭,提高了性能
  • 易于使用:提供簡單的 API,如EnqueueTryDequeue

可用性

  • .NET Framework 4.0 及以上
  • .NET Core 1.0 及以上

示例代碼

using System.Collections.Concurrent;
var queue = new ConcurrentQueue<int>();
var cts = new CancellationTokenSource();
var token = cts.Token;
// 生產(chǎn)者任務
var producer = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        queue.Enqueue(i);
        Console.WriteLine($"Enqueued {i}");
        Thread.Sleep(100); // 模擬生產(chǎn)延遲
    }
}, token);
// 消費者任務
var consumer = Task.Run(() =>
{
    while (!token.IsCancellationRequested)
    {
        if (queue.TryDequeue(out int result))
        {
            Console.WriteLine($"Dequeued {result}");
        }
        Thread.Sleep(50); // 模擬消費延遲
    }
}, token);
await Task.WhenAll(producer);
cts.Cancel(); // 停止消費者任務
await consumer;

2. ConcurrentStack

ConcurrentStack 是一個線程安全的后進先出 (LIFO) 堆棧。它允許多個線程同時進行入棧和出棧操作。

適用場景

  • 深度優(yōu)先搜索算法:在圖或樹結(jié)構(gòu)中進行深度優(yōu)先搜索時使用
  • 撤銷操作:實現(xiàn)撤銷功能時,將操作記錄入棧,撤銷時從棧中彈出操作

優(yōu)點

  • 高效的并發(fā)操作:支持多個線程同時進行入棧和出棧操作
  • 無鎖設計:內(nèi)部使用無鎖算法,避免了鎖競爭,提高了性能
  • 易于使用:提供簡單的 API,如PushTryPop

可用性

  • .NET Framework 4.0 及以上
  • .NET Core 1.0 及以上

示例代碼

using System.Collections.Concurrent;
var stack = new ConcurrentStack<int>();
var cts = new CancellationTokenSource();
var token = cts.Token;
// 生產(chǎn)者任務
var producer = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        stack.Push(i);
        Console.WriteLine($"Pushed {i}");
        Thread.Sleep(100); // 模擬生產(chǎn)延遲
    }
}, token);
// 消費者任務
var consumer = Task.Run(() =>
{
    while (!token.IsCancellationRequested)
    {
        if (stack.TryPop(out int result))
        {
            Console.WriteLine($"Popped {result}");
        }
        Thread.Sleep(50); // 模擬消費延遲
    }
}, token);
await Task.WhenAll(producer);
cts.Cancel(); // 停止消費者任務
await consumer;

3. ConcurrentBag

ConcurrentBag 是一個線程安全的無序集合,適用于頻繁添加和刪除元素的場景。

適用場景

  • 任務池:將任務添加到集合中,工作線程從集合中取出任務并執(zhí)行
  • 緩存:將臨時數(shù)據(jù)存儲在集合中,多個線程可以并發(fā)地添加和刪除數(shù)據(jù)

優(yōu)點

  • 高效的并發(fā)操作:支持多個線程同時進行添加和刪除操作
  • 無鎖設計:內(nèi)部使用無鎖算法,避免了鎖競爭,提高了性能
  • 適用于無序數(shù)據(jù):不關(guān)心元素順序的場景非常適用

可用性

  • .NET Framework 4.0 及以上
  • .NET Core 1.0 及以上

示例代碼

using System.Collections.Concurrent;
var bag = new ConcurrentBag<int>();
var cts = new CancellationTokenSource();
var token = cts.Token;
// 生產(chǎn)者任務
var producer = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        bag.Add(i);
        Console.WriteLine($"Added {i}");
        Thread.Sleep(100); // 模擬生產(chǎn)延遲
    }
}, token);
// 消費者任務
var consumer = Task.Run(() =>
{
    while (!token.IsCancellationRequested)
    {
        if (bag.TryTake(out int result))
        {
            Console.WriteLine($"Took {result}");
        }
        Thread.Sleep(50); // 模擬消費延遲
    }
}, token);
await Task.WhenAll(producer);
cts.Cancel(); // 停止消費者任務
await consumer;

4. ConcurrentDictionary<TKey, TValue>

ConcurrentDictionary<TKey, TValue> 是一個線程安全的鍵值對集合,類似于 Dictionary<TKey, TValue>。

適用場景

  • 緩存:存儲鍵值對數(shù)據(jù),多個線程可以并發(fā)地讀取和寫入緩存
  • 計數(shù)器:存儲計數(shù)器數(shù)據(jù),多個線程可以并發(fā)地更新計數(shù)器值

優(yōu)點

  • 高效的并發(fā)操作:支持多個線程同時進行讀取和寫入操作
  • 原子操作:支持原子操作,如AddOrUpdateGetOrAdd,確保數(shù)據(jù)一致性
  • 靈活性:提供豐富的 API,支持多種操作

可用性

  • .NET Framework 4.0 及以上
  • .NET Core 1.0 及以上

示例代碼

using System.Collections.Concurrent;
var dictionary = new ConcurrentDictionary<int, string>();
// 添加元素
var addTask = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        dictionary.TryAdd(i, $"value{i}");
        Console.WriteLine($"Added key {i} with value value{i}");
    }
});
// 更新元素
var updateTask = Task.Run(() =>
{ 
    for (int i = 0; i < 10; i++)
    {
        var ii = i;
        dictionary.AddOrUpdate(i, $"new_value{i}", (key, oldValue) => $"new_value{ii}");
        Console.WriteLine($"Updated key {i} with value new_value{i}");
    } 
});
// 讀取元素
var readTask = Task.Run(() =>
{
    foreach (var key in dictionary.Keys)
    {
        if (dictionary.TryGetValue(key, out string? value))
        {
            Console.WriteLine($"Key {key} has value {value}");
        }
    }
});
await Task.WhenAll(addTask, updateTask, readTask);

5. BlockingCollection

BlockingCollection 提供線程安全的添加和移除操作,并支持阻塞和限界功能。可以與ConcurrentQueue<T>ConcurrentStack<T>ConcurrentBag<T>等一起使用。

適用場景

  • 生產(chǎn)者-消費者模式:多個生產(chǎn)者線程將數(shù)據(jù)項添加到集合中,多個消費者線程從集合中取出數(shù)據(jù)項進行處理
  • 任務調(diào)度:將任務添加到集合中,由工作線程從集合中取出任務并執(zhí)行

優(yōu)點

  • 阻塞操作:支持阻塞添加和移除操作,適用于生產(chǎn)者-消費者模式
  • 限界功能:支持設置集合的最大容量,防止過度填充
  • 靈活性:可以與多種集合類型一起使用,如ConcurrentQueue<T>

可用性

  • .NET Framework 4.0 及以上
  • .NET Core 1.0 及以上

示例代碼

using System.Collections.Concurrent;
var collection = new BlockingCollection<int>(boundedCapacity: 5);
var cts = new CancellationTokenSource();
var token = cts.Token;
// 生產(chǎn)者任務
var producer = Task.Run(() =>
{
    for (int i = 0; i < 10; i++)
    {
        collection.Add(i);
        Console.WriteLine($"Added {i}");
        Thread.Sleep(100); // 模擬生產(chǎn)延遲
    }
    collection.CompleteAdding();
}, token);
// 消費者任務
var consumer = Task.Run(() =>
{
    foreach (var item in collection.GetConsumingEnumerable(token))
    {
        Console.WriteLine($"Consumed {item}");
        Thread.Sleep(50); // 模擬消費延遲
    }
}, token);
await Task.WhenAll(producer, consumer);

6. ImmutableList

ImmutableList 是線程安全的,因為所有修改操作都會返回一個新的集合實例。

適用場景

  • 配置數(shù)據(jù):存儲配置數(shù)據(jù),多個線程可以并發(fā)地讀取配置數(shù)據(jù),而無需擔心數(shù)據(jù)被修改
  • 快照:在某個時間點獲取數(shù)據(jù)的快照,多個線程可以并發(fā)地讀取快照數(shù)據(jù)

優(yōu)點

  • 天然線程安全:由于集合不可變,多個線程可以安全地并發(fā)讀取
  • 數(shù)據(jù)一致性:所有修改操作都會返回一個新的集合實例,保證數(shù)據(jù)一致性
  • 易于使用:提供豐富的 API,支持多種操作

可用性

  • .NET Framework 4.5 及以上(需要安裝 System.Collections.Immutable NuGet 包)
  • .NET Core 1.0 及以上(需要安裝 System.Collections.Immutable NuGet 包)

示例代碼

var list = ImmutableList.Create(1, 2, 3);
var newList = list.Add(4);
Console.WriteLine(string.Join(", ", newList)); // 輸出 1, 2, 3, 4

7. SynchronizedCollection

SynchronizedCollection 是一個線程安全的集合,適用于需要同步訪問的場景。

適用場景

  • 共享資源管理:管理共享資源的集合,多個線程可以并發(fā)地訪問和修改集合
  • 事件訂閱:存儲事件訂閱者,多個線程可以并發(fā)地添加和移除訂閱者

優(yōu)點

  • 內(nèi)置同步機制:自動處理同步,確保線程安全
  • 易于使用:提供簡單的 API,如AddRemove
  • 靈活性:支持多種集合操作

可用性

  • .NET Framework 3.5 及以上
  • .NET Core 1.0 及以上

示例代碼

var collection = new SynchronizedCollection<int>();
collection.Add(1);
collection.Add(2);
foreach (var item in collection)
{
    Console.WriteLine(item); // 輸出 1 和 2
}

8. SynchronizedReadOnlyCollection

SynchronizedReadOnlyCollection 是一個線程安全的只
讀集合。

適用場景

  • 配置數(shù)據(jù):存儲只讀的配置數(shù)據(jù),多個線程可以并發(fā)地讀取配置數(shù)據(jù)
  • 共享數(shù)據(jù):存儲共享數(shù)據(jù),多個線程可以并發(fā)地讀取數(shù)據(jù),而無需擔心數(shù)據(jù)被修改

優(yōu)點

  • 內(nèi)置同步機制:自動處理同步,確保線程安全
  • 易于使用:提供簡單的 API,如ContainsCopyTo
  • 數(shù)據(jù)保護:只讀特性確保數(shù)據(jù)不會被修改

可用性

  • .NET Framework 3.0 及以上
  • .NET Core 1.0 及以上

示例代碼

var list = new List<int> { 1, 2, 3 };
var readOnlyCollection = new SynchronizedReadOnlyCollection<int>(list);
foreach (var item in readOnlyCollection)
{
    Console.WriteLine(item); // 輸出 1, 2, 3
}

9. SynchronizedKeyedCollection<K, T>

SynchronizedKeyedCollection<K, T> 是一個線程安全的鍵控集合。

使用場景

  • 緩存:存儲鍵控數(shù)據(jù),多個線程可以并發(fā)地讀取和寫入緩存
  • 資源管理:管理鍵控資源的集合,多個線程可以并發(fā)地訪問和修改集合

優(yōu)點

  • 內(nèi)置同步機制:自動處理同步,確保線程安全
  • 鍵控訪問:支持通過鍵快速訪問元素
  • 靈活性:支持多種集合操作

可用性

  • .NET Framework 3.0 及以上
  • .NET Core 1.0 及以上

示例代碼

public class MyItem
{
    public int Id { get; set; }
    public string Name { get; set; }
}
var collection = new SynchronizedKeyedCollection<int, MyItem>(item => item.Id);
collection.Add(new MyItem { Id = 1, Name = "Item1" });
collection.Add(new MyItem { Id = 2, Name = "Item2" });
foreach (var item in collection)
{
    Console.WriteLine(item.Name); // 輸出 Item1 和 Item2
}

到此這篇關(guān)于.NET 中的線程安全數(shù)據(jù)結(jié)構(gòu)的文章就介紹到這了,更多相關(guān).NET線程安全數(shù)據(jù)結(jié)構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論