Many people look at the Interlocked methods and wonder why Microsoft doesn't create a richer set of interlocked methods that can be used in a wider range of scenarios. For example, it would be nice if the Interlocked class offered Multiply, Divide, Minimum, Maximum, And, Or, Xor, and a bunch of other methods. Although the Interlocked class doesn’t offer these methods, there is a well-known pattern that allows you to perform any operation on an Int32 in an atomic way by using Interlocked.CompareExchange. In fact, because Interlocked.CompareExchange has additional overloads that operate on Int64, Single, Double, Object, and a generic reference type, this pattern will actually work for all these types, too.

This pattern is similar to optimistic concurrency patterns used for modifying database records. Here is an example of the pattern that is being used to create an atomic Maximum method.

Now let me explain exactly what is going on here. Upon entering the method, currentVal is initialized to the value in target at the moment the method starts executing. Then, inside the loop, startVal is initialized to this same value. Using startVal, you can perform any operation you want. This operation can be extremely complex, consisting of thousands of lines of code. But, ultimately, you must end up with a result that is placed into desiredVal. In my example, I simply determine whether startVal or value contains the larger value.

Now, while this operation is running, another thread could change the value in target. It is unlikely that this will happen, but it is possible. If this does happen, then the value in desiredVal is based off an old value in startVal, not the current value in target, and therefore, we should not change the value in target. To ensure that the value in target is changed to desiredVal if no thread has changed target behind our thread’s back, we use Interlocked.CompareExchange. This method checks whether the value in target matches the value in startVal (which identifies the value that we thought was in target before starting to perform the operation). If the value in target didn’t change, then CompareExchange changes it to the new value in desiredVal. If the value in target did change, then CompareExchange does not alter the value in target at all.

CompareExchange returns the value that is in target at the time when CompareExchange is called, which I then place in currentVal. Then, a check is made comparing startVal with the new value in currentVal. If these values are the same, then a thread did not change target behind our thread’s back, target now contains the value in desiredVal, the while loop does not loop around, and the method returns. If startVal is not equal to currentVal, then a thread did change the value in target behind our thread’s back, target did not get changed to our value in desiredVal, and the while loop will loop around and try the operation again, this time using the new value in currentVal that reflects the other thread’s change.

Personally, I have used this pattern in a lot of my own code and, in fact, I made a generic method, Morph, which encapsulates this pattern.

最新文章

  1. mongodb安装启动遇到的问题
  2. qq空间返回顶部代码
  3. css知多少(1)——我来问你来答
  4. loadrunner安装汉化破解
  5. 第二个Sprint冲刺第十天
  6. 火狐firefox提示“内容编码错误 无法显示您尝试查看的页面,因为它使用了无效或者不支持的压缩格式。”
  7. HDU 5861 Road (线段树)
  8. Oracle11g使用exp导出空表
  9. Android 显示原理简介
  10. 现代程序设计——homework-08
  11. 在Eclipse中添加添加一些有助于开发的插件
  12. Spring之SpringMVC前端控制器DispatcherServlet(源码)分析
  13. Bucket Sort - leetcode [桶排序]
  14. Ubuntu Intel显卡驱动安装 (Ubuntu 14.04--Ubuntu 16.10 + Intel® Graphics Update Tool)
  15. Linux安装NodeJS
  16. java 动态绑定 多态
  17. URL URI
  18. PHP-CPP开发扩展(三)
  19. mysql 数据表操作 目录
  20. uva-10391-枚举

热门文章

  1. 【LOJ】#2065. 「SDOI2016」模式字符串
  2. Kafka/Metaq设计思想学习笔记
  3. 005 Hadoop的三种模式区别
  4. R语言实战(九)主成分和因子分析
  5. 使用apache的ab命令进行压测
  6. BoneBlack am335x利用SD卡烧写板卡上的emmc
  7. 转 SSM框架整合to萌新
  8. CORS跨域请求[简单请求与复杂请求]
  9. blog搬家啦
  10. 【Floyd矩阵乘法】BZOJ1706- [usaco2007 Nov]relays 奶牛接力跑