概述
原子性:要么做,要么都不做。并发中,可能会出现++,但实际没加上的情况
可见性:一个线程要看到其他线程修改的最新值。并发中,jmm主内存工作内存之分,所以看到的不是其他内存最新值,导致逻辑代码失效。
有序性:按照代码书写顺序执行。编译器会指令重排,并发中,会导致逻辑代码失效,如new 对象。
java解决方案
原子性:cas、synchronized、lock。synchronized、lock,获取锁时会读取主内存最新数据,释放锁会将工作内存数据回写
可见性:volatile、synchronized、lock。
有序性:volatile、synchronized、lock。
jmm
jmm:工作内存和主内存。8种操作。从主内存读取、放入工作内存、从工作内存取出使用,分别是read、load、use。给工作内存赋值、从工作内存取出、存入主内存是asign、store、write。还有两种是lock和unlock作用于主内存变量,表示只能给一个线程使用,lock的话会使当前工作内存失效需要把主内存刷新到工作内存,unlock会把工作内存刷新到主内存的或其他
volatile原理
volatile的底层是用JMM内存屏障来实现的,再底层是用操作系统内存屏障来实现的。
volatile读/写后的操作都不能到前面去,有StoreStore、StoreLoad、LoadStore、LoadLoad屏障等 JMM内存屏障,其底层是操作系统内存屏障如lfence、sfence、mfence、lock(不是屏障是总线锁,但能达到一样的效果)
happens-before
这是jmm给程序员的承诺。
1)程序顺序规则:一个线程中的每个操作,happens-before于该线程中的任意后续操作;
2)锁定规则:对一个锁的解锁,happens-before于随后对这个锁的加锁;
2.4 happens-before
happens-before的定义
as-if-serial语义保证单线程内程序的执行结果不被改变
happens-before关系保证正确同步的多线程程序的执行结果不被改变。
happens-before规则
3)volatile变量规则:对一个volatile变量的写操作,happens-before于任意后续对这个volatile变量
的读操作;
4)传递规则:如果A happens-before B,并且B happens-before C,则A happens-before C;
5)线程启动规则:如果线程A调用线程B的start()方法来启动线程B,则start()操作happens-before
于线程B中的任意操作;
6)线程中断规则:对线程interrupt()方法的调用happens-before于被中断线程的代码检测到中断事
件的发生;
7)线程终结规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作
happens-before于线程A从ThreadB.join()操作成功返回;
8)对象终结规则:一个对象的初始化完成happens-before于它的finalize()方法的开始。