JMM
volatile
volatile是Java虚拟机提供的轻量级同步机制
它的三个特性:
- 保证可见性
- 不保证原子性
- 禁止指令重排
JMM相关的一些同步约定:
1、线程解锁前,必须把共享变量立刻刷回主存
2、线程加锁前,必须读取主存中的最新值到工作内存中
3、加锁和解锁是同一把锁
不保证原子性的测试实例:
package com.sw.volatileDemo;
import java.util.concurrent.TimeUnit;
/**
* @Author suaxi
* @Date 2021/2/19 22:07
*/
public class JMMTest {
private static int num = 0;
public static void main(String[] args) { //main线程
new Thread(() ->{ //线程1
while (num == 0){
}
}).start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
num = 1;
System.out.println(num); //输出num=1,main线程将num改为1后,线程1还在循环while(num == 0)
}
}
JMM对八种指令的使用制定了如下规则:
- 不允许read和load、store和write操作单独出现,即:使用read必须load,使用store必须write
- 不允许线程丢弃它最近的assign操作,即:工作变量(工作内存中)的数据改变了之后,必须告知主存
- 不允许一个线程将没有assign的数据从工作内存同步回主内存
- 一个新的变量必须在主内存中诞生,不允许工作内存直接使用一个未被初始化的变量,即:对变量进行use、store操作之前,必须经过assign和load操作
- 一个变量同一时间只有一个线程能对其进行lock。多次lock后,必须执行相同次数的unlock才能解锁
- 如果对一个变量进行lock操作,会清空所有工作内存中此变量的值,在执行引擎使用这个变量之前,必须重新load或assign操作初始化变量的值
- 如果一个变量没有被lock,就不能对其进行unlock操作,也不能unlock一个被其他线程锁住的变量
- 对一个变量进行unlock之前,必须把此变量同步回主内存
评论 (0)