1.可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
多线程修改共享变量的操作如果符合happens-before规则,则JMM可以保证这个变量的可见性。
happens-before规则
1.程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作。
happens-before仅仅要求前一个操作(执行的结果)对后一个操作可见,并不意味着前一个操作必须要在后一个操作之前执行。
一个方法中相邻的2行代码不一定按从上到下的顺序执行:JMM允许编译器和处理器对指令重排序。
as-if-serial语义:不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。
编译器、runtime和处理器都必须遵守as-if-serial语义。编译器和处理器不会对存在数据依赖关系的操作做重排序。
2.监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
3.volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。
4.传递性:如果A happens-before B,且B happens-before C,那么A happens-before C。
2.原子性:一个线程的某个操作不会被其他线程打断。
synchronized/CAS保证原子性。
Atomic原子类为什么可以保证原子性:基于Unsafe的CAS方法,Unsafe循环CAS。
CAS概念
1.CAS的全称为Compare-And-Swap ,它是一条CPU并发原语。
2.操作系统原语是由若干条指令组成,用于完成某个功能的一个过程。原语的执行必须是连续的,在执行过程中不允许中断。
3.CAS是一条系统原语,也即是说CAS是一条原子指令,不会造成所谓的数据不一致的问题。
CAS作用
1.判断内存某个位置的值是否为预期值,如果是则更新为新的值,这个过程是原子的。
CAS缺点
1.循环时间长的话开销很大(高并发场景下只有1个线程CAS成功,其他线程都CAS失败进入死循环,会消耗CPU)。
2.只能保证1个共享变量的原子性。
3.ABA问题:狸猫换太子。如何解决:AtomicStampedReference