原子性:不可中断的一系列指令
处理器如何实现原子性
处理器基于对总线加锁和缓存加锁的方式来实现多处理器之间的原子操作。
总线加锁:只有一个处理器能处理这个内存,其他处理器的所有请求都被阻塞,该处理器独占共享内存。
缓存锁定:通过缓存一致性协议,保证同一时刻只有一个处理器能操作某一块内存
java中原子性的实现
在java中是通过锁和循环CAS来实现原子操作的
使用CAS实现原子性
JVM的CAS是利用了CMPXCHG指令实现的。
自旋CAS就是CAS操作直到成功。
原子类:AtomicBoolean,AtomicLong,AtomicInteger,AtomicBoolean。
这些类提供了CAS和原子加1的方法。
CAS相比锁的优势:不用上下文切换
CAS三大问题
(1)ABA问题,JDK的Atomic包的类的compareAndSet方法会检查版本号,从而避免ABA。
(2)循环时间长,需要加最大重试次数,然后抛出异常处理。
(3)只能保证一个变量的原子操作。java推出了AtomicReference 类:
do {
oldPair = pairRef.get();
newPair = new Pair(newFirst, newSecond);
} while (!pairRef.compareAndSet(oldPair, newPair));
使用锁来实现原子操做
无论是偏向锁,轻量级锁,互斥锁,都用了循环CAS,当一个线程想进入同步块中时使用CAS来获取锁,当它退出时使用循环CAS释放锁。