C#线程同步

devtools/2024/9/24 5:25:39/

c#线程同步代码示例

仔细考虑下面这段代码是不是输出0

    const int _max = 1000000;private int _count = 0;void Start(){Task task = Task.Run(() =>{Decr();});for (int i = 0; i < _max; i++){_count++;}task.Wait();Debug.Log(_count);}void Decr(){for(int i = 0; i < _max; i++){_count--;}}

下面这个代码呢

const int _max = 1000000;private int _count = 0;object _sync = new object();void Start(){Task task = Task.Run(() =>{Decr();});for (int i = 0; i < _max; i++){lock (_sync){_count++;   }}task.Wait();Debug.Log(_count);}void Decr(){for(int i = 0; i < _max; i++){lock (_sync){_count--;   }}

将要访问_Count的代码段锁定了之后(用lock)​,Main()和Decr()方法就是线程安全的。换言之,可从多个线程中同时安全地调用它们

即使为了同步的需要可以忍受lock的速度,也不要在多处理器计算机中不假思索地添加同步来避免死锁和不必要的同步(也许本来可以并行执行的)​。

object 必须是引用类型的对象。如果你尝试将一个值类型(如结构体或基本数据类型如 int)作为 lock 语句的参数,编译器会报错。例如:

int myLock = 0;
lock (myLock) // 编译错误:不能将值类型作为 lock 的参数
{// 代码
}

这会导致编译错误,因为 myLock 是一个 int,它是一个值类型。正确的做法是使用一个引用类型的对象作为锁

为什么要避免锁定this、typeof(type)和string

一个貌似合理的模式是锁定代表类中实例数据的this关键字,以及为静态数据锁定从typeof(type)(例如typeof(MyType))获取的类型实例。在这种模式下,使用this可为与特定对象实例关联的所有状态提供同步目标;使用typeof(type)则为一个类型的所有静态数据提供同步目标。但这样做的问题在于,在另一个完全不相干的代码块中,可能创建一个完全不同的同步块,而这个同步块的同步目标可能就是this(或typeof(type))所指向的同步目标。换言之,虽然只有实例自身内部的代码能用this关键字来阻塞,但创建实例的调用者仍可将那个实例传给一个同步锁。

简单来说  经常锁定this,调用者无意间可能也把这个对象当作锁,有死锁的隐患

要避免的另一个锁定类型是string,这是因为要考虑到字符串留用问题。如同一个字符串常量在多个位置出现,那么所有位置都可能引用同一个实例,使锁定的范围大于预期

将字段声明为volatile

编译器和/或CPU有时会对代码进行优化,使指令不按照它们的编码顺序执行,或干脆拿掉一些无用指令。若代码只在一个线程上执行,像这样的优化无伤大雅。但对于多个线程,这种优化就可能造成出乎预料的结果,因为优化可能造成两个线程对同一字段的读写顺序发生错乱。

解决该问题的一个方案是用volatile关键字声明字段。该关键字强迫对volatile

字段的所有读写操作都在代码指示的位置发生,而不是在通过优化而生成的其他某个位置发生。volatile修饰符指出字段容易被硬件、操作系统或另一个线程修改。所以这种数据是“易变的”​(volatile)​,编译器和“运行时”要更严谨地处理它。

一般很少使用volatile修饰符。即便使用,也可能因为疏忽而使用不当。lock比volatile更好,除非对volatile的用法有绝对的把握。


http://www.ppmy.cn/devtools/104300.html

相关文章

智能分拣投递机器人

产品介绍 自研智能分拣投递机器人&#xff0c;专注于物流行业“NC小件”的分拣与投递&#xff0c;机器人运行稳定、分拣效率高&#xff0c;搭配智能分拣投递系统单台机器人最大作业效率可达400件/H&#xff0c;投递效率相较于传统“小黄人“提升了30%-50%&#xff0c;可替代“…

分享 11 个常用的 Nginx 性能优化参数工作

原文链接&#xff1a;分享 11 个常用的 Nginx 性能优化参数工作-腾讯云开发者社区-腾讯云 分享 11 个常用的 Nginx 性能优化参数教程 工作上&#xff0c;需要配置 Nginx&#xff0c;要投入生产使用&#xff0c;做了一点优化工作&#xff0c;加上以前也经常折腾 Nginx&#xff…

Python编程实例-使用Pandas处理数据集中的异常值

使用Pandas处理数据集中的异常值 文章目录 使用Pandas处理数据集中的异常值1、检测异常值2、处理异常值2.1 移除异常值2.2 截断异常值2.3 插补异常值2.4 应用转换异常值是指与数据集中其他观测值显著不同的观测值,它们可能由于实验误差、测量误差或数据本身存在的变异性而产生…

足浴城消费系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;商品分类管理&#xff0c;商品信息管理&#xff0c;购买信息管理&#xff0c;会员卡申请管理&#xff0c;包厢信息管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;公告…

智普大模型API调用

接口 用python调用智普免费API接口的例子,写成函数, 类似于 def get_answer(prompt):url = http://34.132.32.68:8081/v1/chat/completionsheaders = {Content-Type: application/json,}data = {"model": "Qwen2-72B-int4","messages": [{&q…

Linux系统安装nginx

目录 一、下载软件包二、安装依赖三、安装Nginx四、启动&停止五、配置systemd方式管理NG六、启动&停止七、实验测试 一、下载软件包 网址&#xff1a;https://nginx.org/ 二、安装依赖 yum -y install gcc pcre-devel zlib-devel openssl openssl-devel 三、安装…

spring boot 项目 prometheus 自定义指标收集和 grafana 查询--方法耗时分位数指标

auth author JellyfishMIX - github / blog.jellyfishmix.comLICENSE LICENSE-2.0 说明 网上有很多 promehteus 和 grafana 配置&#xff0c;本文不再重复&#xff0c;只介绍自定义部分。目前只介绍了分位数指标的收集和查询&#xff0c;常用于方法耗时的指标监控。 自定义…

20行为型设计模式——访问者模式

一、访问者模介绍 访问者模式&#xff08;Visitor Pattern&#xff09;是一种行为型设计模式&#xff0c;用于将操作封装在访问者对象中&#xff0c;以便在不改变被访问对象的类的前提下&#xff0c;定义新的操作。它允许你在不修改现有代码的情况下&#xff0c;向对象结构中添…