C#中Dictionary与ConcurrentDictionary解锁多线程操作安全之道

开发 后端
在C#中,Dictionary是一个常见的字典类型,但它不是线程安全的。为了在多线程环境中确保安全的操作,我们可以使用ConcurrentDictionary,这是一个专门设计用于多线程场景的线程安全字典。

使用C#中的Dictionary与ConcurrentDictionary进行多线程操作

在C#中,Dictionary是一个常见的字典类型,但它不是线程安全的。为了在多线程环境中确保安全的操作,我们可以使用ConcurrentDictionary,这是一个专门设计用于多线程场景的线程安全字典。

1. 使用Dictionary进行非线程安全操作

首先,我们来看一个使用普通的Dictionary的例子。在这个例子中,我们创建一个Dictionary对象,然后通过多个线程同时进行读取和写入操作,以演示潜在的线程安全问题。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        // 创建一个非线程安全的 Dictionary
        Dictionary<int, string> regularDictionary = new Dictionary<int, string>();

        // 启动多个线程对字典进行读取和写入操作
        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 10; i++)
        {
            int key = i;

            tasks.Add(Task.Run(() =>
            {
                // 读取和写入操作
                RegularDictionaryExample(regularDictionary, key);
            }));
        }

        // 等待所有任务完成
        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("Regular Dictionary:");
        PrintDictionary(regularDictionary);

        Console.ReadLine();
    }

    // 非线程安全的字典操作示例
    static void RegularDictionaryExample(Dictionary<int, string> dictionary, int key)
    {
        if (dictionary.ContainsKey(key))
        {
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} already exists. Value: {dictionary[key]}");
        }
        else
        {
            dictionary[key] = $"Value from Thread {Thread.CurrentThread.ManagedThreadId}";
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} added.");
        }
    }

    // 打印字典内容
    static void PrintDictionary<T, U>(Dictionary<T, U> dictionary)
    {
        foreach (var kvp in dictionary)
        {
            Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }
}

2. 使用ConcurrentDictionary进行线程安全操作

接下来,我们使用ConcurrentDictionary来解决线程安全问题。ConcurrentDictionary提供了内置的线程安全机制,避免了多线程同时访问时的问题。

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        // 创建一个线程安全的 ConcurrentDictionary
        ConcurrentDictionary<int, string> concurrentDictionary = new ConcurrentDictionary<int, string>();

        // 启动多个线程对字典进行读取和写入操作
        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 10; i++)
        {
            int key = i;

            tasks.Add(Task.Run(() =>
            {
                // 读取和写入操作
                ConcurrentDictionaryExample(concurrentDictionary, key);
            }));
        }

        // 等待所有任务完成
        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("\nConcurrent Dictionary:");
        PrintDictionary(concurrentDictionary);

        Console.ReadLine();
    }

    // 线程安全的字典操作示例
    static void ConcurrentDictionaryExample(ConcurrentDictionary<int, string> dictionary, int key)
    {
        string value = dictionary.GetOrAdd(key, k => $"Value from Thread {Thread.CurrentThread.ManagedThreadId}");
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} {((value == null) ? "added" : "already exists")}. Value: {value}");
    }

    // 打印字典内容
    static void PrintDictionary<T, U>(ConcurrentDictionary<T, U> dictionary)
    {
        foreach (var kvp in dictionary)
        {
            Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }
}
  • Dictionary问题: 普通的Dictionary在多线程环境中可能导致数据不一致或异常,因为它不提供线程安全性。
  • ConcurrentDictionary解决方案: ConcurrentDictionary是专为多线程设计的,通过提供内置的线程安全机制,确保在多线程环境中对字典进行安全的读取和写入操作。
  • GetOrAdd方法: ConcurrentDictionaryGetOrAdd方法是线程安全的读取和写入的原子操作,可以安全地在多线程环境中使用。

通过选择适当的字典类型,可以确保在多线程应用程序中有效地管理数据,避免潜在的线程安全问题。

责任编辑:姜华 来源: 今日头条
相关推荐

2009-08-17 16:56:51

C#多线程控制进度条

2022-09-16 06:59:49

api线程安全

2009-07-17 10:37:05

C#多线程

2011-04-25 14:42:10

C#lock

2009-08-12 18:04:44

编写C#多线程

2024-03-12 10:25:14

C#Dictionary编程语言

2015-07-28 10:06:03

C#内部实现剖析

2024-02-27 10:44:58

C#线程后端

2009-08-21 11:31:59

异步和多线程的区别

2009-09-04 15:09:48

C#多线程启动Squa

2009-08-28 16:43:57

C#多线程学习

2009-08-17 16:41:03

C#多线程控制

2009-08-17 16:29:56

C#多线程控制

2009-08-26 18:13:55

C#多线程lock

2024-02-02 18:29:54

C++线程编程

2015-04-01 14:34:37

C#dynamicDictionary性

2009-08-24 18:15:24

C# Dictiona

2009-08-04 17:57:41

C#线程同步死锁

2009-09-01 17:15:42

C#多线程应用

2015-11-24 15:13:15

点赞
收藏

51CTO技术栈公众号