处理器实现原子操作
- 使用总线锁保证原子性 ==
使用处理器提供的一个LOCK#信号,当一个处理器在总线上输出此信号时,其他处理器的请求将被阻塞,那么处理器可以独占共享内存。 - 使用缓存锁保证原子性
缓存锁定是指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,那么当它执行锁操作回写到内存时,处理器不在总线上声言LOCK#信号,而是修改内部的内存地址,并允许它的缓存一致性机制来保证操作的原子性,因为缓存一致性机制会阻止同时修改两个以上处理器缓存的内存区域数据。当其他处理器回写已被锁定的缓存行的数据时,会使缓存行无效。
处理器不会使用缓存锁定情况
- 当操作的数据不能被缓存在处理器内部或操作的数据跨多个缓存行时,则处理器会调用总线锁定。
- 有些处理器不支持缓存锁定
java实现原子操作
1. 使用循环CAS实现原子操作
CAS操作需要输入两个数值,一个旧值和一个新值,在操作期间先比较旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。
存在问题
- ABA问题
一个值从A变到B再变到A
----使用Atomic包中的AtomicStampedReference来解决问题,(使用版本号区分))
这个类的CompareAndSet方法作用是首先检查当前引用是否等于预期引用,并且检查当前标志是否等于预期标志,如果全部相等则更新。 - 循环时间长开销大
自旋CAS长时间不成功,会造成cpu开销大
-----处理器的pause指令
它可以延迟流水线执行指令,使CPU不会消耗过多的资源,还可以避免在退出循环的时候因内存顺序冲突而引起CPU流水线被清空,从而提高CPU的执行效率。 - 只能保证一个共享变量的原子操作
----使用AtomicReference类保证引用对象之间的原子性,将多个共享变量合并成一个。
–使用锁
2 使用锁机制实现原子操作
除了偏向锁,JVM实现锁的方式都用了循环CAS,当一个线程进入一个同步块的时候使用循环CAS方式来获取锁,当它退出同步块的时候使用循环CAS释放锁。