volatile
- 保证线程可见性
- MESI(缓存一致性协议) - 禁止指令重排序
- DCL单例
- Double Check Lock
Volatile不能保证原子性
volatile并不能保证多个线程共同修改变量时带来的不一致问题,也就是说volatile不能替代synchronized。
synchronized优化
作为synchronized,如果竞争较少应使同步代码较少。
锁定某个对象o,如果o的属性发生改变,不影响锁的使用,但是如果o变成另外一个对象,则锁定的对象发生改变,应该避免将锁定对象的引用变成另外的对象。
CAS(无锁优化,自旋)
解决同样的问题的更高效的方法,使用AtomXXX类,其本身方法都是原子性的,但不能保证多个方法连续调用都是原子性的。这里只列举AtomicInteger类中的方法。
最后找到这行代码如下:
public final native boolean compareAndSwapInt(Object var1, long var2, int var4, int var5);
这个方法是调用的unsafe类里的方法,compareAndSwap就是CAS,字面意思比较并且设定,CAS是CPU原语支持的,也就是说中间不能被打断。
cas(V,Expected,NewValue)
- if V == E
- V = New
- otherwise try again or fail
ABA问题
如果是引用类型,加version即可解决。