jmm是java虚拟机内存模型,他是一种规范,描述了各个变量之间的关系,以及在实际计算机系统中将变量存储到内存以及中内存中取出变量的细节。
jmm有三大特点,分别是有序性、原子性以及可见性。
1、可见性,可见性即是线程修改变量参数后,其他线程也可以看到。因为在java中,线程会将主内存中的数据缓存到线程中的高速缓存区中,这将导致主内存中的变量被修改后,线程读取的数值仍然是修改前的,这就是线程之间的不可见性。解决方案有@valitile 变量
2、原子性,原子性即是一个事务一旦开始就不会被其他的线程中断。而中断主要是由cpu的切换引起,主要的解决方案是加锁,syn或reentrantlock都可以
3、有序性,java虚拟机在编译代码时,会在不影响单线程结果的前提下进行指令重排,这主要是由计算机的三级缓存引起的。指令重排在单线程下不会有什么影响,但在并发场景中会有较多问题。比如
public demo(){
boolean isReady = true;
int age = 111;
new Thread(item->{
age = 666;
isReady = false;
}).start();
new Thread(item->{
while(isReady);
age += 222;}).start();
}
代码中,从常理看 age 一定等于888 但是因为指令重拍原因,age最后可能是333 和888两种情况。解决指令重排的方法一般有valitile关键字