- JMM

- 可见性:就是某个线程对主内存内容的更改,应该立刻通知到其它线程
- 原子性:指一个操作是不可分割的,不能执行到一半,就不执行了
- 有序性:就是指令是有序的,不会被重排
- volatile关键字
- 描述:volatile关键字是Java提供的一种轻量级同步机制。它能够保证可见性和有序性,但是不能保证原子性
- 例子
- 单例模式的安全问题
- CAS
描述:CAS是指Compare And Swap,比较并交换,底层调用了Unsafe.getAndAddInt()方法,Unsafe类的大部分方法都是native的。
public final int getAnddAddInt(Object var1,long var2,int var4){int var5;do{var5 = this.getIntVolatile(var1, var2);} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));return var5;}
原理:这个方法的var1和var2,就是根据对象和偏移量得到在主内存的快照值var5。然后compareAndSwapInt方法通过var1和var2得到当前主内存的实际值。如果这个实际值跟快照值相等,那么就更新主内存的值为var5+var4。如果不等,那么就一直循环,一直获取快照,一直对比,直到实际值和快照值相等为止。
缺点
- 一直循环,CPU开销比较大
- 只能保证一个变量的原子操作,多个变量依然要加锁
- 引出了ABA问题
相关问题
- ABA问题:比较并交换的循环,存在一个时间差,线程T1将值从A改为B,然后又从B改为A。线程T2看到的就是A,但是却不知道这个A发生了更改,如果只注重头和尾就不影响。
- 解决办法:加版本号,例如AtomicStampedReference就是通过加版本号ABA问题的解决的。
- ABA问题:比较并交换的循环,存在一个时间差,线程T1将值从A改为B,然后又从B改为A。线程T2看到的就是A,但是却不知道这个A发生了更改,如果只注重头和尾就不影响。
