JUC -> Java.util.current
volatile: 轻量级的同步机制
- 保证可见性
- 不保证原子性
- 禁止指令重排序
JMM(JAVA Memory Model) :Java内存模型(抽象规范)
- 可见性:当某一个线程从主内容读取变量到自己的工作内存,在本地自己的工内存修改值后刷新回主内存,其他本地内存拥有该变量的值会被强制重新从主内存读取变量值
- 原子性:操作要么同时成功,要么同时失败
例子:i++ ,i++在指令中可大体可分为3步
- 获取i的值
- i+1
- 返回i的值
在此过程中,其他线程有可能修改i的值,所以是非线程安全
解决原子性有两个方式: Synchronize 关键字
使用JUC包下的AtomicIntger等带原子性的封装类
指令重排序:在单线程下指令重排序不会影响最后执行结果,而在多线程下有可能发生数据错乱。
禁止指令重排序的原理就是在增加内存屏障,内存屏障前后可以进行指令重排序
volatile的应用:
- 单例模式
单例模式是线程不安全的
解决办法:DCL(Double Check Lock 双端捡锁机制)与Volatile
DCL(Double Check Lock 双端捡锁机制):
倘若单单使用DCL还是线程不安全,因为有可能发生指令重排序
构造一个对象可以分为3步
- 分配对象内存空间
- 初始化对象
- 引用变量指向内存地址
这三步可能发生指令重排序,如果3和2重排序,那么指针将指向一个地址不为空,内容却为空的对象