C#多线程数据同步的几种方式(不同的锁)

news2024/9/30 21:15:05

无锁

多个关联数据无法完整获取修改

 internal class Program
 {
     static void Main(string[] args)
     {
         Console.WriteLine("Hello, World!");
         ThreadPool.QueueUserWorkItem(Thread1);
         ThreadPool.QueueUserWorkItem(Thread2);
         ThreadPool.QueueUserWorkItem(Thread3);

         Console.ReadKey();
     }

     public static int[] Datas = new int[3];

     public static void Thread1(object o)
     {
         Datas[0] = 100;
         Thread.Sleep(5000);
         Datas[1] = 101;
         Thread.Sleep(2000);
         Datas[2] = 120;
     }

     public static void Thread2(object o)
     {
         while (true)
         {
             Console.WriteLine($"Thread2:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]}");

             Thread.Sleep(1000);
         }
     }

     private static void Thread3(object? state)
     {
         while (true)
         {
             Console.WriteLine($"Thread3:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]}");

             Thread.Sleep(1000);
         }
     }
 }

在这里插入图片描述

加上lock锁

每次需要等其他线程解锁了才能用

在这里插入图片描述

自旋锁

遇到上锁时,短暂循环等待,线程不挂起

internal class Program
{
    static int _lock = 0;

    static void Main(string[] args)
    {
        Console.WriteLine("Hello, World!");
        Console.WriteLine($"time:{DateTime.Now.ToString("HH:mm:ss.fff")}");
        ThreadPool.QueueUserWorkItem(Thread1);
        ThreadPool.QueueUserWorkItem(Thread2);
        ThreadPool.QueueUserWorkItem(Thread3);

        Console.ReadKey();
    }

    public static int[] Datas = new int[3];

    public static void Thread1(object o)
    {
        while (Interlocked.Exchange(ref _lock, 1) != 0)
        {
            Thread.SpinWait(1);
        }

        Datas[0] = 100;
        Thread.Sleep(5000);
        Datas[1] = 101;
        Thread.Sleep(2000);
        Datas[2] = 120;
        Console.WriteLine($"write finish,time:{DateTime.Now.ToString("HH:mm:ss.fff")}");
        //lock (Datas)
        //{

        //}
        Interlocked.Exchange(ref _lock, 0);
    }

    public static void Thread2(object o)
    {
        while (true)
        {
            while (Interlocked.Exchange(ref _lock, 1) != 0)
            {
                Thread.SpinWait(1);
            }
            //lock (Datas)
            //{
            Console.WriteLine(
                $"Thread2:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]},time:{DateTime.Now.ToString("HH:mm:ss.fff")}"
            );
            Thread.Sleep(1000);
            //}
            Interlocked.Exchange(ref _lock, 0);
        }
    }

    private static void Thread3(object? state)
    {
        while (true)
        {
            while (Interlocked.Exchange(ref _lock, 1) != 0)
            {
                Thread.SpinWait(1);
            }
            Console.WriteLine(
                $"Thread3:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]},time:{DateTime.Now.ToString("HH:mm:ss.fff")}"
            );

            Thread.Sleep(1000);
            Interlocked.Exchange(ref _lock, 0);
        }
    }
}

读写锁

写入时,唯一线程写入,读的时候可以多个线程同时读取
在这里插入图片描述

    internal class Program
    {
        static ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");
            Console.WriteLine($"time:{DateTime.Now.ToString("HH:mm:ss.fff")}");
            ThreadPool.QueueUserWorkItem(Thread1);
            ThreadPool.QueueUserWorkItem(Thread2);
            ThreadPool.QueueUserWorkItem(Thread3);

            Console.ReadKey();
        }

        public static int[] Datas = new int[3];

        public static void Thread1(object o)
        {
            _lock.EnterWriteLock();

            try
            {
                Datas[0] = 100;
                Thread.Sleep(5000);
                Datas[1] = 101;
                Thread.Sleep(2000);
                Datas[2] = 120;
                Console.WriteLine($"write finish,time:{DateTime.Now.ToString("HH:mm:ss.fff")}");
            }
            catch (Exception) { }
            finally
            {
                _lock.ExitWriteLock();
            }
        }

        public static void Thread2(object o)
        {
            while (true)
            {
                _lock.EnterReadLock();
                try
                {
                    Console.WriteLine(
                        $"Thread2:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]},time:{DateTime.Now.ToString("HH:mm:ss.fff")}"
                    );
                    Thread.Sleep(1000);
                }
                catch (Exception) { }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private static void Thread3(object? state)
        {
            while (true)
            {
                _lock.EnterReadLock();
                try
                {
                    Console.WriteLine(
                        $"Thread3:0->{Datas[0]},1->{Datas[1]},2->{Datas[2]},time:{DateTime.Now.ToString("HH:mm:ss.fff")}"
                    );

                    Thread.Sleep(1000);
                }
                catch (Exception) { }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2180713.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot框架在墙绘产品展示中的运用

4 系统设计 墙绘产品展示交易平台的设计方案比如功能框架的设计,比如数据库的设计的好坏也就决定了该系统在开发层面是否高效,以及在系统维护层面是否容易维护和升级,因为在系统实现阶段是需要考虑用户的所有需求,要是在设计阶段没…

linux查看进程所在的目录

在Linux系统中,查看一个进程所在的目录(即该进程的可执行文件所在的目录)可以通过多种方式实现。 以下是查找进程的可执行文件路径的方法: 使用ls -l /proc/[pid]/cwd 你可以通过查看/proc/[pid]/cwd的符号链接来找到进程的可执…

UE5蓝图实战:动态墙上挖坑与自定义坑尺寸

在Unreal Engine 5.3中,我利用蓝图系统开发了一个创新的挖坑Demo,该Demo展示了如何在实时环境中动态地在墙体上挖坑,并允许用户自定义坑的大小。这一过程得益于UE5官方提供的Geometry Script插件,该插件通过蓝图接口实现了强大的网…

sql-labs:42~65

less42(单引号闭合、报错回显) login_useradmin login_password123 and if(11,sleep(2),1) # # 单引号闭合 ​ login_useradmin login_password123and updatexml(1,concat(0x7e,database(),0x7e),1)# # 报错回显…

端模一体,猎豹移动对大模型机器人发展路径清晰

今年世界机器人大会刚刚收官不久,接咖啡、拿苹果、摊煎饼……人形机器人在这届大会上备受关注,厂商们编排“整活”,展位几乎水泄不通。 自从AI大模型开始全面改变市场开始,关于机器人的方向性争论就不绝于耳,就在最近的…

北京中实新材料:携手知名建筑企业,共筑重大工程辉煌篇章

近年来,北京中实新材料有限责任公司(以下简称“北京中实”)凭借其卓越的产品质量、专业的技术服务和良好的市场信誉,积极参与了一系列重大工程项目的建设,与多家知名建筑企业建立了长期稳定的合作关系,共同书写了城市发展的辉煌篇章。 深耕行业,铸就品质基石 自成立以来,北京中…

Python查漏补缺

1.冒泡排序 时间复杂度O(n^2) 选择、插入都是 def bubble(data, reverse):for i in range(len(data)-1):for j in range(len(data)-i-1):if data[j] > data[j1]:data[j], data[j1] data[j1], data[j]if reverse:data.reverse()return data 2.快速排序 时间…

《OpenCV 计算机视觉》—— 图像拼接

还未写完!!! 下面是两张需要拼接的图片 完整代码: import cv2 import numpy as np import sysdef cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(0)def detectAndDescribe(image):gray cv2.cvtColor(image, cv2.COLOR_…

mobile_aloha训练过程中pycharm编辑器遇到的问题记录

目前在研究mobile aloha的训练算法部分,运行文件为imitate_episodes.py,对应指令: # To train ACT: python3 imitate_episodes.py --task_name mobile_imu --ckpt_dir /home/song/hjx/aloha/mobile-aloha_multi-sensor/ckpt/mobile_imu --pol…

Mac屏蔽系统更新,取出红点标记如果解锁hosts文件

引言:关闭系统更新,首先应该在系统偏好设置---软件更新---去掉自动更新的选项。即使如此,系统仍然进行macOS系统和自带safari等软件的检测更新,并图标右上角红点点标记提醒我们更新,那我们如果彻底屏蔽更新呢&#xff…

计算机毕业设计 基于爬虫与文本挖掘的网络舆情监控系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…

网站建设公司如何选?2024专业网站建设公司哪家好TOP3

要找一家靠谱的网站建设公司,可以根据以下五点判断: 1.企业的工商信息 企业有多少人、什么时候成立的、成立资金是多少、是否有违约记录这些都可以在查企业的那种app里可以看到,去查的时候一定要仔细甄别,别最后找了一家皮包公司…

HarmonyOS/OpenHarmony Audio 实现音频录制及播放功能

关键词:audio、音频录制、音频播放、权限申请、文件管理 在app的开发过程中时常会遇见一些需要播放一段音频或进行语音录制的场景,那么本期将介绍如何利用鸿蒙 audio 模块实现音频写入和播放的功能。本次依赖的是 ohos.multimedia.audio 音频管理模块&am…

基于Python大数据可视化的短视频推荐系统

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…

大模型压缩3种方式;模型大小的计算;知识蒸馏:利用教师的输入输出,训练调整学生的小模型

目录 大模型压缩3种方式 模型大小的计算 知识蒸馏:利用教师的输入输出,训练调整学生的小模型 最终学生学习多个教师的知识,学生强大 大模型压缩3种方式 模型大小的计算 知识蒸馏:利用教师的输入输出,训练调整学生的小模型

商务英语口语柯桥外语学习|ass是“屁股”,save是“救”,那 save my ass是什么意思?

有些人活着,屁股却已经“死”了 工作工作,上工就“坐”,“久坐”几乎是无法避免的事情,但你知道吗,长期久坐可能会患上死臀综合症(Dormant Butt Syndrome)! 如果你坐久了就觉得屁股痛…

imagickd写shell的技术学习

前言 没想到吧哥们,imagickd也能写shell,真是学到了不少,下面会具体分析是如何写shell的 基础知识 Imagick类 参考官方手册https://www.php.net/manual/zh/class.imagick.php 重点关注他的构造方法 (PECL imagick 2, PECL imagick 3) …

基于vue框架的大学生兼职平台r8x19(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能:企业,用户,兼职信息,报名记录,岗位类型,专业,取消记录,评价记录 开题报告内容 基于Vue框架的大学生兼职平台开题报告 一、开题报告名称 基于Vue框架的大学生兼职平台 二、研究背景与意义 2.1 研究背景 随着高等教育的普及和就业市…

https访问报错:net::ERR_CERT_DATE_INVALLD

目录 简介异常排查原因解决补充 简介 访问https资源出现报错 异常 排查 将地址拿到浏览器进行访问,可以很清晰的看到出现该问题的原因 原因 1、SSL证书已过期 2、服务器日期不准,不在证书有效期 解决 1、重新申请SSL证书,并配置 2、校正…

平安养老险深圳分公司积极开展“金融教育宣传月”活动,展现金融为民新风尚

2024年9月,平安养老险深圳分公司以“金融为民谱新篇,守护权益防风险”为主题,正式启动2024年“金融教育宣传月”活动,通过多样化开展进乡村、进商圈、进企业等宣传教育活动,将金融消保知识送达广大消费者身边&#xff…