上面代码中,有一个点解释一下Interlocked.CompareExchange(ref _firstItem, null, item) != item
,其中!=item
,如果其等于item
就说明交换成功了,当前线程获取到_firstItem
元素的期间没有其它线程修改_firstItem
的值 。
Return 方法Retrun(T obj)
方法是ObjectPool
另外一个重要的方法,它的作用就是当程序代码把从池中获取的对象使用完以后,将其归还到池中 。同样,它也使用CAS
指令来解决多线程资源争用的问题,代码如下所示:
public override void Return(T obj){// 使用策略的Return方法对元素进行处理// 比如 List<T> 需要调用Claer方法清除集合内元素// StringBuilder之类的也需要调用Claer方法清除缓存的字符if (_isDefaultPolicy || (_fastPolicy?.Return(obj) ?? _policy.Return(obj))){// 先尝试将归还的元素赋值到 _firstItem中if (_firstItem != null || Interlocked.CompareExchange(ref _firstItem, obj, null) != null){var items = _items;// 如果 _firstItem已经存在元素// 那么遍历整个数组空间 找一个存储为null的空位将对象存储起来for (var i = 0; i < items.Length && Interlocked.CompareExchange(ref items[i].Element, obj, null) != null; ++i){}}}}
从核心的Get()
和Set()
方法来看,其实整个代码是比较简单的,除了有一个_firstItem
有一个简单的优化,其余没有什么特别的复杂的逻辑 。
主要的关键就在Interlocked.CompareExchange
方法上,我们在下文来仔细研究一下这个方法 。
关于 Interlocked.CompareExchangeInterlocked.CompareExchange
它实际上是一个CAS
的实现,也就是Compare And Swap,从名字就可以看出来,它就是比较然后交换的意思 。
从下面的代码段我们也可以看出来,它总共需要三个参数 。其特性就是只有当localtion1 == comparand
的时候才会将value
赋值给localtion1
,另外吧localtion1
的原始值返回出来,这些操作都是原子性的 。
// localtion1 需要比较的引用A// value 计划给引用A 赋的值// comparand 和引用A比较的引用public static T CompareExchange<T> (ref T location1, T value, T comparand)where T : class;
一个简单的流程如下所示:
文章插图
简单的使用代码如下所示:
【从ObjectPool到CAS指令】
var a = 1;// a == 1的话就将其置为0// 判断是否成功就看返回的值是否为a的原始值if(Interlocked.CompareExchange(ref a, 0, 1) == 1) Console.WriteLine("1.成功");// 现在a已经变为0 这个交换不会成功if(Interlocked.CompareExchange(ref a, 0, 1) == 1) Console.WriteLine("2.成功");
结果如下所示,只有当a
的原始值为1
的时候,才会交换成功:文章插图
那么
Interlocked.CompareExchange
是如何做到原子性的?在多核CPU中,数据可能在内存或者L1、L2、L3中(如下图所示),我们如何保证能原子性的对某个数据进行操作?文章插图
实际上这是CPU提供的功能,如果查看过JIT编译的结果,可以看到
CompareExchange
是由一条叫lock cmpxchgl
的汇编指令支撑的 。文章插图
其中
lock
是一个指令前缀,汇编指令被lock
修饰后会成为"原子的",lock
指令有两种实现方法:- 早期 - Pentium时代(锁总线),在Pentium及之前的处理器中,带有
经验总结扩展阅读
- 2023年9月16日买宠物好不好 2023年9月16日买宠物行吗
- 2023年9月16日买鸡好吗 2023年9月16日买鸡行吗
- 2023年农历八月初二买鱼吉日 2023年9月16日买鱼吉日一览表
- 2023年农历八月初二宜买鸭吗 2023年9月16日买鸭好吗
- 圣诞节祝福问候语
- 2023年9月16日买牛吉日一览表 2023年9月16日买牛好吗
- 游乐场的万圣节祝福语
- 为什么大部分冰箱都是从左往右开门 冰箱是怎么发明出来的
- 五险一金到底是怎么算的 离职后怎么处理五险一金
- 2023天气太热幽默朋友圈文案怎么发 表达天气热到爆炸的搞笑句子说说