首页 > 编程语言 >C#中Dictionary与ConcurrentDictionary解锁多线程操作安全之道

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

时间:2024-01-22 09:04:37浏览次数:26  
标签:Thread Dictionary C# ConcurrentDictionary 线程 key 多线程

 

使用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方法: ConcurrentDictionary的GetOrAdd方法是线程安全的读取和写入的原子操作,可以安全地在多线程环境中使用。

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

标签:Thread,Dictionary,C#,ConcurrentDictionary,线程,key,多线程
From: https://www.cnblogs.com/hanbing81868164/p/17979223

相关文章

  • Elastic学习之旅 (2) 快速安装ELK
    大家好,我是Edison。上一篇:初识ElasticSearchElasticSearch的安装方式ElasticSearch可以有多种安装方式,比如直接下载安装到宿主机进行运行,也可以通过docker的方式运行,完全取决我们的用途。这里,我们只是为了学习和练习,通过docker方式运行即可。Docker安装的前置条件这里为了成......
  • [转帖]MySQL多版本并发控制机制(MVCC)-源码浅析
    https://zhuanlan.zhihu.com/p/144682180 MySQL多版本并发控制机制(MVCC)-源码浅析前言作为一个数据库爱好者,自己动手写过简单的SQL解析器以及存储引擎,但感觉还是不够过瘾。<<事务处理-概念与技术>>诚然讲的非常透彻,但只能提纲挈领,不能让你玩转某个真正的数据库。感谢c......
  • [转帖]CIDR
    什么是CIDR?无类别域间路由(CIDR)是一种IP地址分配方法,可提高互联网上的数据路由效率。每台连接到互联网的计算机、服务器和最终用户设备都有一个与之关联的唯一编号,称为IP地址。设备通过使用这些IP地址相互查找和通信。组织使用CIDR在其网络中灵活高效地分配IP......
  • Teamcenter SOA重置密码
    一、TeamcenterSOA重置密码importcom.teamcenter.services.internal.loose.administration.UserManagementService;UserManagementServiceuseRestService=UserManagementService.getService(AppXSession.getConnection());try{booleanisSuccess=useRestSer......
  • DC-7靶机做题记录
    靶机下载地址:链接:https://pan.baidu.com/s/1w2c_QKd_hOoR2AzNrdZjMg?pwd=tdky提取码:tdky参考:DC7靶机地址:http://www.five86.com/downloads/DC-7.zipDC7靶场介绍:https://www.vulnhub.com/entry/dc-7,356/php插件地址:https://ftp.drupal.org/files/projects/php-8.x-1.x......
  • 基于CMFB余弦调制滤波器组的频谱响应matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a 3.算法理论概述        CMFB余弦调制滤波器组是一种基于余弦调制技术的滤波器组,它具有频率选择性和可调性,可以广泛应用于信号处理、图像处理、通信等领域。下面将详细介绍其原理、数学公式等。 3.1......
  • 多线程笔记
    线程创建继承Thread类//线程创建方式1:继承thread1,重写run方法,调用start开启线程publicclassThread1extendsThread{@Overridepublicvoidrun(){//run方法线程体for(inti=0;i<20;i++){System.out.println("我在看代......
  • fwrite、fread——《初学C语言第59天》
     ////————————fwrite//#include<stdio.h>//structS//{// chararr[10];// intage;// floatscore;//};//intmain()//{// structSs={"zhangjie",25,50.25};// //以二进制的形式写到文件中// FILE*pf=fopen("text.txt","wb");//......
  • PHP学习第八天:扩展开发与多线程编程
    在PHP学习的第八天,我深入了解了扩展开发和多线程编程的概念。早上,我学习了如何编写PHP扩展。扩展是PHP的模块,可以提供额外的功能。我了解了扩展开发的基础知识,如C语言和PHPAPI。通过编写一个简单的扩展,我熟悉了扩展的结构和编写过程。了解扩展开发使我能够更深入地了解PHP的内部工......
  • 无涯教程-CodeIgniter - MVC框架
    CodeIgniter基于模型-视图-控制器(MVC)开发模式。MVC是一种将应用程序逻辑与表示分离的软件方法。Model    - 代表数据模型,主要跟数据库打交道,实现无涯教程的CURD封装。View      - 是前台展示给用户看的界面。Controller - Model和View的桥梁......