volitile
可变的、易变的
保证线程可见性、禁止指令重排。但不能保证原子性
volitile应用场景
Lazy DCL、Double Check Sync
volitile特性
禁止指令重排
CPU实现:lfence,sfence,mfence原语
JVM实现SS,LL,SL,LS屏障
Volitile实现:写操作只有写完之后才能进行读操作
读操作只有读完之后才能进行写操作
保证线程可见性
通过硬件CPU,缓存一致性协议(MESI)
通过及时将工作内存写入主内存,保证线程间可见性。
synchronized粗化细化
细化:当业务逻辑只需要在方法中的一小部分需要sync,不需要给整个方法上锁
粗化:当业务逻辑在方法中对多个部分上锁,最好直接给方法上锁
synchronized使用要点
1、sync是对对象进行上锁,当对对象进行上锁后,改变了对象将造成问题。所以要在对象声明时加上final
2、不要已字符串类型作为锁对象,很有可能造成死锁阻塞,因为很可能程序和类库使用了同一把锁
CAS(无锁优化,自旋,乐观锁)
Unsafe:Compare and swap
CAS(value,Expected,NewValue)
if v == e
v == new
otherwise try again or fail
CPU原语支持,操作时不允许插入
ABA问题:一个线程将A->B,一个线程将B-A。引用类型会有问题(引用已经历过了修改),基础数据类型问题不大。
通过增加版本号来判断(AtomicStampedReference)
JUC下atomic包下,都是CAS实现的
Unsafe
直接操作内存:allocateMemory
直接生成类实例:allocateInstance
直接操作类或实例变量:getObject
CAS相关操作:compareAndSwap Object int long