Java 内存模型
JMM
目的:
屏蔽硬件和操作系统的内存访问差异
主要作用:
定义程序各个变量的访问规则
定义变量的存储获取规则
变量的额定义:
包括实例字段、静态字段、构建数组对象的元素
局部变量和方法参数
这些是线程私有的不会被共享不存在竞争问题
定义
1.它的一些规定 所有的变量存储在主存
2.每条线程拥有自己的工作内存 可类比高速缓存
3.工作内存拷贝了一份该线程所需要变量的主内存中的副本
4.线程对变量的所有操作(读取,赋值)必须在工作内存中。
5.线程之间的变量值的传递需要通过主内存来完成
如果一定要和运行时数据区对应
主内存对应堆中的对象实例数据
工作内存 对应栈中的部分区域。
交互操作
内存之间的交互操作
定义了8中原子性的操作
lock 作用范围主内存
unlock
read 传输
write
load 放
use 给执行引擎
assgin 执行引擎接收到的值赋给工作内存的变量
store 返回
规则
read load/ store/write
在定义时只保证顺序执行,不保证连续执行
规则
先行发生
read/load store/write
不能丢弃assgin
不允许工作内存“诞生”
lock可重入
lock 清空某一变量的值 重新read load assgin
unlock只允许用在自己线程的lock变量
unlock结束 会执行同步
volatile特殊性
可以说是轻量级的同步机制
1.可见性
可见性 是一个线程改变可变量 新值对其他线程是可以立即获得的。普通变量需要一部主存同步
volatile的特殊性 都需要先刷新 执行引擎看不到不一致的情况
非原子性原因 :
1.Java中的运算并非原子操作,字节码可解析为若干条机器码
i++
1 getstatic i; 保证值是正确的
2 iconst_1;
3 iadd ;
4 putstatic
在2-3步骤中其他线程可能对i进行了改变
而且字节码指令也并非是原子可见解析为若干条机器码
什么情况下还需要在加锁
只有单一线程修改该变量
通常需要在结合sychronized 原子类
线程池停止时可用????
2.禁止指令重优化
普通变量
可以保证:在该方法执行过程中所有依赖结果的地方得到正确值
不能保证:复制顺序和代码顺序一致
结果是 线程内表现为串性
DCL单例 1.5之后才有的
实现原理:内存屏障 lock 做到屏障隔离
虚拟机对锁的很多优化和消除
volatile的写会操作略慢 因为需要插入内存屏障来保证处理器不乱序
volatile的特殊规则
T VW
T 前一个是load 才能执行use 就是read load use关联
规则 保证使用V前需要从主存刷新最新值 用于保证其他线程能看见修改后的值
2.assgin store write关联 保证每次修改后会立即同步
3.T 对V的read 优先于T 对W的read ,那么T对V的loa use也依次优先于T对W的动作
可见性还可以通过sychronized final
寄存器、高速缓存、指令集
JDK JSR133
有序性:
天然有序性 是指 在本线程内的所有操作都是有序的
在一个线程看另外一个线程所有操作时无序的
前半句是 线程内表现为串行
后半句描述了 指令重排 和同步延迟