更新时间:2022-10-02 13:48:57
在大多数计算机上,增加变量操作不是一个原子操作,需要执行下列步骤:
1. 将实例变量中的值加载到寄存器中。
2. 增加或减少该值。
3. 在实例变量中存储该值。
在多线程环境下,线程会在执行完前两个步骤后被抢先。然后由另一个线程执行所有三个步骤,当第一个线程重新开始执行时,它覆盖实例变量中的值,造成第二个线程执行增减操作的结果丢失。
Interlocked可以为多个线程共享的变量提供原子操作。
但是Interlocked并没有为乘法,除法提供原子操作。那么如何实现乘法,除法,以及为其他的一些非原子操作提供原子操作的支持呢??
关键就在于Interlocked.CompareExchange 中,Jeffrey Richter把它叫做InterLocked Anything 模式。
下面我们使用Interlocked.CompareExchange 实现求最大值的原子操作。
这段代码的核心就是:currentVal = Interlocked.CompareExchange(ref target, desiredVal, startVal);
// 将target的值和startVal的值比较,相等则用desiredVal替换target,否则不操作,
//不管替换还是不替换返回的都是原来保存在target的值。
在这里,计算可能会比较复杂,而不像上面的Math.Max一样,所以可以使用委托调用的方式进行封装。
基本原理和上面的一致。