【并发编程042】CAS操作的原理?
CAS操作的原理?
CAS: Compare and Swap, 即比较再交换。
jdk5 增加了并发包 java.util.concurrent.*, 其下面的类使用 CAS 算法实现了区别于 synchronized 悲 观锁的一种乐观锁 。JDK 5 之前 Java 语言是靠 synchronized 关键字保证同步的, 这是一种独占锁, 也是是悲观锁。
所谓的 CAS, 其实是个简称, 全称是 Compare And Swap, 对比之后交换数据 。 上面的方法, 有几 个重要的参数:
(1) this, Unsafe 对象本身, 需要通过这个类来获取 value 的内存偏移地址。
(2) valueOffset, value 变量的内存偏移地址。
(3) expect, 期望更新的值。
(4) update, 要更新的最新值。
其中步骤 (1) 和步骤 (2) 是根据内存偏移地址获取当前的值value, expect值是未修改之前的value 值 。 如果修改时通过内存偏移地址获取到的value与except的value值一样, 则进行更新, 否则不更新, 再次从新获取value值, 循环下去, 直到成功为止 。 (通过源码阅读)
这里看到有一个 LOCK_IF_MP, 作用是如果是多处理器, 在指令前加上 LOCK 前缀, 因为在单 处理器中, 是不会存在缓存不一致的问题的, 所有线程都在一个 CPU 上跑, 使用同一个缓存区, 也就不存在本地内存与主内存不一致的问题, 不会造成可见性问题 。 然而在多核处理器中, 共 享内存需要从写缓存中刷新到主内存中去, 并遵循缓存一致性协议通知其他处理器更新缓存 。 Lock 在这里的作用:
• 在 cmpxchg 执行期间, 锁住内存地址 [edx], 其他处理器不能访问该内存, 保证原子性 。 即 使是在 32 位机器上修改 64 位的内存也可以保证原子性。
• 将本处理器上写缓存全部强制写回主存中去, 保证每个线程的本地内存与主存一致。
• 禁止 cmpxchg 与前后任何指令重排序, 防止指令重排序。
相关文章
- Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响
- python并发编程之进程、线程、协程的调度原理(六)
- 嵌入式(字符设备驱动基础下_并发控制)
- 《Java 并发编程的艺术》迷你书
- 定制并发类(五)在一个Executor对象中使用我们的ThreadFactory
- 定制并发类(三)实现一个基于优先级的Executor类
- 《C#并发编程经典实例》—— 发送通知给上下文
- 并发编程 - synchronized的特性与底层原理以及锁的状态和膨胀升级过程
- Java并发——Executor框架详解(转)
- Java并发编程 - 基本概念
- 单线程解决高并发的思路
- 多线程中的并发,并行与串行的区别
- 什么是高并发 ,详细讲解
- 《Haskell并行与并发编程》——第2章,第2.3节示例:并行化数独解算器
- 《Java线程与并发编程实践》—— 第2章 同步 2.1 线程中的问题
- 《C++并发编程实战》——第1章 你好,C++并发世界
- 【Java并发编程】并发编程大合集-值得收藏
- Java并发编程:并发容器之ConcurrentHashMap(转载)
- Java_并发工具包 java.util.concurrent 用户指南(转)
- JUC 并发编程学习笔记(上)
- Java并发编程(十四)Java内存模型
- springmvc在使用@ModelAttribute注解获取Request和Response会产生线程并发不安全问题(续)
- 学习笔记(02):Python网络编程&并发编程-assert断言的用途
- C#-并发编程之【四】响应式编程简介