聊聊Interlocked.CompareExchange吧?

【导读】私下空余时间一直在研究开源框架,当然也就少不了学习优秀源码,本文也是我查看有关源码时,触碰到我个人知识盲区,做此记录,分享下

Interlocked.CompareExchange这玩意用法被讲的很烂了,为何再次被提及,主要看了下官网对其使用描述可能对于部分童鞋来讲具备一定迷惑性,需我们进一步消化下,话不多讲,我们来看看吧~~~

浅谈如标题

关于啥时候用此语法,这.....此处省略若干字,上代码

var location = 1;var value = 3;var compared = 1;Interlocked.CompareExchange(ref location, value, compared);

若原始值(location)与比较值(compared)一致,则将当前值(value)替换原始值。如图上述,此时原始值将为3,毫无疑问,我们很清楚这是基本用法

问题来了,该语法既可比较基本类型也可比较引用类型

当比较对象时,官方还特此备注注意:

比较对象的引用相等性,而不是值相等性。结果,两个具有相同值类型(例如,整数3)的装箱实例始终看起来不相等,并且不执行任何操作。不要将此重载用于值类型。


初次看,稍不注意的迷惑性来了,解释如下截图

从描述上看,一部分童鞋是不是会认为,原始值为空,则会引发空引用异常,如下代码

object o1 = null;object o2 = null;Interlocked.CompareExchange(ref o1, o2, null);

运行上述代码将不会抛出空引用异常,这是为何?难道官方解释有误,接下来我们深入探讨下

深谈如标题

若对C语言有所了解,则不会存在疑惑,官方解释为空指针(不是空),而我们代码是空引用,二者不可同日而语

C#中对于引用类型,定义现有的变量必将存在引用,所以在C#中不可能存在空引用,所以我们是不是可以认为必然不会存在抛出空引用异常

官方解释为空指针和null其实并不是同一个概念,如此一解释,极易引起概念混淆,还不如去掉,显得有点多余

再想想,也不是那么绝对,个人以为,至少在托管情况下理论上应该不会抛出任何异常,非托管情况下可能没有保证,或者通过IL操作底层,也会触发上述空引用异常

综上个人理解,官方解释谈不上迷惑性,只是好像有点会引起概念混淆,让部分童鞋以为不能传递空,希望没将各位绕晕

那么我们在哪些场景下会用到上述原始值为空的情况呢?比如确保对象初始化,如下:

public class Order
{public Address Address{get{return CreateAddress();}}private Address CreateAddress() => new Address();
}public class Address
{
}

当我们在Order内部使用Address时,确保其实例已完全初始化,如下:

static Address EnsureAddressInitialized()
{var order = new Order();Func<Order, Address> func = f => f.Address;Address target = null;var result = Interlocked.CompareExchange(ref target, func(order), null);Console.WriteLine(result == null);Console.WriteLine(target);return target!;
}

上述方法返回对象实例时,我们使用C# 8.0语法表明对象实例绝不可能为空

该语法有返回值,那打印结果是否和替换后的原始值一样呢?不是,除了替换原始值外,针对所有情况,返回值都是最初原始值即旧值。

据我所知,该语法底层直接操作CPU处理器指令,当然也是原子性操作,即便是操作系统也无法执行中断操作,线程可以在指令执行之前被抢占,但在指令执行期间不会被抢占,换言之,绝不会出现,当原始值和比较值比较相等时,而另一线程指令更改原始值的情况

基于上述理论,所以才有了网上大多数通过循环方式对其返回结果赋最新原始值实现并发无锁修改操作

public static Address EnsureAddressInitialized(ref Address target,Order order, Func<Order, Address> func){if (target != null){return target;}while (Interlocked.CompareExchange(ref target, func(order), null) == null){break;}return target;}

为避免上述没必要的循环操作,同时也为避开CPU缓存,我们进一步进行代码优化,通过使用Volatile关键字获取内存最新存储数据,最终演变成如下这般

public static Address EnsureAddressInitialized(ref Address target,Order order, Func<Order, Address> func)
{var tmp = Volatile.Read(ref target);if (tmp != null){return tmp;}Interlocked.CompareExchange(ref target, func(order), null);return target!;
}

???? 概念的混淆可能会存在使用上的疑惑,同时我们基于理论逐步优化,实现并发无锁修改操作

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

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

相关文章

sae 本地环境 mysql数据库_SAE本地环境与真实环境的差别

其实从刚开始用的时候就发现本地环境和真实环境有不同&#xff0c;导致本地环境我都没怎么用。1、本地环境的php是32bit版本的&#xff0c;真实环境是64bit的。这是我发现的第一个不相同的地方&#xff0c;就是因为这个&#xff0c;直接导致我的应用绝大部分调试工作都是在把代…

winform 统计大量数据重复的元素个数_面试系列:十个海量数据处理方法大总结...

本文将简单总结下一些处理海量数据问题的常见方法。当然这些方法可能并不能完全覆盖所有的问题&#xff0c;但是这样的一些方法也基本可以处理绝大多数遇到的问题。下面的一些问题基本直接来源于公司的面试笔试题目&#xff0c;方法不一定最优&#xff0c;如果你有更好的处理方…

C# 实现一个基于值相等性比较的字典

C# 实现一个基于值相等性比较的字典Intro今天在项目里遇到一个需求&#xff0c;大概是这样的我要比较两个 JSON 字符串是不是相等&#xff0c;JSON 字符串其实是一个 Dictionary<string, string> 但是顺序可能不同&#xff0c;和上一篇 record 使用场景中的第一个需求类似…

RIAMeeting第六次开发者交流活动。

5月的一场大地震带给我们过多的悲痛&#xff0c;但国家还要兴起&#xff0c;技术还要进步&#xff0c;让广大RIA开发者化悲愤为力量&#xff0c;继续开创中国的RIA事业吧&#xff01; 本月的25日&#xff0c;RIAMeeting将举办第六次开发者交流活动&#xff0c;本次活动邀请到了…

java字符串转时间_java字符串和时间转换

import java.text.SimpleDateFormat; import java.util.Date; //将long字符串转换成格式时间输出 public class LongToString {public static void main(String argsp[]){String time="1256006105375"; Date date=new Date(Long.parseLong(time)); SimpleDateFormat …

java 堆栈_Java中线程与堆栈的关系

栈是线程私有的&#xff0c;每个线程都是自己的栈&#xff0c;每个线程中的每个方法在执行的同时会创建一个栈帧用于存局部变量表、操作数栈、动态链接、方法返回地址等信息。每一个方法从调用到执行完毕的过程&#xff0c;就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。其…

巧用lock解决缓存击穿的解决方案

背景缓存击穿是指缓存中没有但数据库中有的数据&#xff08;一般是缓存时间到期&#xff09;&#xff0c;这时由于并发用户特别多&#xff0c;同时读缓存没读到数据&#xff0c;又同时去数据库去取数据&#xff0c;引起数据库压力瞬间增大&#xff0c;造成过大压力。解决方案1、…

ISA禁止了symantec的LiveUpdate的使用

从我们服务器将symantec升级到10.1.5.5000后&#xff0c;就发现ISA客户端的用户&#xff0c;用LiveUpdate没法升级&#xff0c;点击按钮后也会运行升级&#xff0c;但是到最后总是出现一个红色的大叉&#xff0c;说升级失败。这样客户端就只剩下手动用升级包升级或者是通过服务…

java怎么将前端的数据存到关联的表中_Java程序员最可能被考到的14个面试题

1. 如何只扫描一遍就找到位于一个链表正中间的元素&#xff1f; 这是最受欢迎的算法题之一&#xff0c;经常在电话面试中被问到。很多程序员会想&#xff0c;要知道链表的长度&#xff0c;就要先扫描一遍链表&#xff0c;然后在第二遍中取其正中的元素。所以被要求只扫描一遍就…

java 监听文件内容_java 监听文件内容变化

有时候&#xff0c;我们需要确定某些文件是否有变化而做出一些对应的动作&#xff0c;例如&#xff0c;曾经开发的一款服务器中&#xff0c;由于模块比较多&#xff0c;在运行期间有时候需要单独的输出某个模块日志&#xff0c;但又不可能总是开着日志。log4j中已经实现了可以动…

.NET Core 和 .NET Framework 启动可执行文件的差别

在 Windows 下&#xff0c;使用 .NET Framework 构建出来的应用&#xff0c;可以只有一个可执行文件&#xff0c;在可执行文件里面包含了 IL 代码。使用 .NET Core 构建出来的应用&#xff0c;将会包含一个 Exe 可执行文件&#xff0c;和对应的 Dll 文件&#xff0c;而 IL 代码…

firefox 3.0 在 windows 下的编译

&#xff08;1&#xff09;下载firefox 3.0源代码。下载并安装 mozilla-build &#xff08;2&#xff09;运行 start-msvc9.bat&#xff0c;进入shell界面&#xff0c; 查看环境变量&#xff1a; echo $PATH echo $LIB echo $INCLUDE &#xff08;3&#xff09;确保: windo…

常见的几种最优化方法

阅读目录1. 梯度下降法&#xff08;Gradient Descent&#xff09;2. 牛顿法和拟牛顿法&#xff08;Newtons method & Quasi-Newton Methods&#xff09;3. 共轭梯度法&#xff08;Conjugate Gradient&#xff09;4. 启发式优化方法我们每个人都会在我们的生活或者工作中遇到…

安卓平板运行python_使用Python进行手机平板移动开发 | 学步园

过去&#xff0c;Android和iOS上的移动应用程序开发不是Python的强项&#xff0c;但情况可能会发生变化……使用Python进行移动应用开发怎么样&#xff1f;从历史上看&#xff0c;在编写移动GUI应用程序时&#xff0c;Python并没有很强的故事。实际上&#xff0c;仅使用纯Pytho…

专业的软件安装包可以这样做!

C/S客户端开发完成&#xff0c;需要将程序交付给用户&#xff0c;直接压缩发给用户是可以的&#xff08;只是有点不专业&#xff09;&#xff0c;如果能有一个比较好看的安装界面&#xff0c;那档次就不一样了。本文介绍怎么使用Adanced Installer 17.9 制作专业的Windows 客户…

jsp需要多少java基础_Java基础——JSP(一)

注意&#xff1a;访问JSP的过程如果是第一次访问服务器&#xff0c;则翻译成一个对应的java文件(Servlet)。然后&#xff0c;再被编成 .class 文件并加载到内存中。如果是以后访问&#xff0c;则直接调用内存中的jsp实例&#xff0c;所以第一次访问慢,以后访问会更加快。四、3种…

宝贝,对不起

宝贝&#xff0c;对不起 题记:读在地震中用生命保护三个月大的婴儿的伟大母亲的遗言 “亲爱的宝贝&#xff0c;如果你能活着&#xff0c;请一定要记得我爱你”有感 谨以此文献给那逝去的伟大母亲和幸存下来坚强的宝贝 ——代腾飞 2008年5月21日 于成都 面对这突如其来的空前灾…

IT人喝酒,不同岗位不同姿势

这是Boss们的常用套路&#xff0c;频频举杯&#xff0c;给大家鼓劲加油&#xff0c;但是自己不喝。有的销售&#xff0c;业绩好&#xff0c;酒品也好&#xff0c;不管和自己人喝酒&#xff0c;还是和客户喝酒&#xff0c;都是一副舍我其谁的霸气&#xff01;这是某些销售的写照…

国产CPU群雄逐鹿谁主沉浮

当下&#xff0c;国内&#xff08;桌面、服务器&#xff09;CPU与外商有较大差距&#xff0c;除了海光在性能上可能具有一拼之力外&#xff0c;其它国产CPU在商业市场上面对英特尔、AMD基本不具备竞争力&#xff0c;因而只能在篱笆墙内的市场角逐。而为了能够进入篱笆墙内的市场…

让网站性能最佳的34条黄金守则

Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践。他们为此进行了一系列的实验、开发了各种工具、写了大量的文章和博客并在各种会议上参与探讨。最佳实践的核心就是旨在提高网站性能。Excetional Performance团队总结出了一系列可以提高网站速度的方法。可以分…