内存模型
Java原生支持多线程,这种模型是为了适配不同操作系统架构。屏蔽掉系统和底层硬件的差异。工作模型如下:
JVM的内存模型是JVM定义抽象的定义。
工作内存对应的JVM哪一个模块不重要因为,不同的JVM实现,实现的也不一样。
数据八大原子操作
- lock: 作用于主内存的变量,把一个变量标记为一条线程独占状态。
- unlock:与loc相反的操作。
- read: 作用于主内存的变量,把一个变量从主内存传输到线程的工作内存中,以便后续的load动作。
- load: 作用于工作内存的操作,把read操作从主内存中得到的变量放入工作内存的变量副本中。
- use: 作用于工作内存的操作,把工作内存中的一个变量值传给执行引擎。
- assign: 作用于工作内存,把一个从执行引擎接收到的值赋值给工作内存的变量。
- store: 作用于工作内存,把工作内存中的一个变量的值传送到主内存中,以便随后的write。
- write:作用于工作内存,把store操作从工作内存中的一个变量的值传送到主内存变量中。
来:lock->read->load->use
去:assign->store->write->unlock
内存可见性
关键词:MESI 协议
volatile 用于保证有序性 解决可见性问题
syncronized用于保证原子性
volatile 解决可见性问题 保证及时看到。不加的话,也有可能看到。只是不及时。
如何理解:
JVM定义的这些模型语义,不会去描述多线程程序如何执行,而是描述多线程程序于许表现出来的行为。任何执行策略,只要产生的是允许的行为,那他就是一个可以接受的策略。
空循环优先级超高。
synronized可以保证内存块操作的原子性。
指令重排
as-if-serial
happen-before
volatile指令重排优化
内存屏障是cpu指令,作用两个:
- 保证特定操作的执行顺序。
- 保证某些变量的可见性。(volatile的可见性)
原理:内存屏障技术
ifence: 一种Load barrier读屏障。
sfence: 一种Store Barrier写屏障
mfence : 全能型屏障,具备ifence和sfence能力。
Lock前缀 Lock不是一种内存屏障,但是它能完成类似内存屏障的功能。Lock会对CPU总线和高速缓存加锁,可以理解为PUC指令的一种锁。它后面可以跟 ADD,ADC,AND,BTC,BTR,BTS,CMPXCHG,CMPXCH8B,DEC,INC,NEG,NOT,OR,SBB,SUB,XOR,XADD,and XCHG指令。
手动加内存屏障
Unsafe.fullFence
java中的可见性如何保证:
归类有两种:
- OrderAccess::storeLoad
lock; addl xxxx X86架构 lock替代mfence
java: volatile,final,syncronized,sleep - 上下文切换 Thread.yield
CPU 等待唤醒。所有切换都是 park,unpark。操作系统库函数:
Linux: pthread_cond_timewait
spl.park