标签:image def vol -- 改变 interrupt 虚拟 com java学习
作用:
保证线程间变量的可见性(注意:不是线程之间的变量可见)
线程A对变量X进行修改后,在线程A后面执行的其他线程能看到变量X的变动。
需要符合以下两个规则:
线程对变量进行修改之后要立刻写回到主内存--->防止主内存与工作内存中不一致的情况
加了volitale修饰,对变量的修改就会立刻写到主内存当中
同时通知另一个线程拿到最新的
线程对变量读取的时候要从主内存中读,而不是从缓存中读
线程工作模式图:
特点:
各线程的工作内存间彼此独立、互不可见。
在线程启动的时候,虚拟机为每个内存分配一块工作内存。
包含了线程内部定义的局部变量
线程所需要使用的共享变量(非线程内构造的对象)的副本
volatile的缺陷:--->只保证了同步的数据可见
volatile不能保证原子性
什么是原子性?
以代码a++举例,在汇编层面会分成三步
拿到a
a+1计算结果
存储计算的结果到a中
这完整的三步是一个整体、一个变量。--->volatile不能保证这三个作为一个整体发生变化
package thread.rearrangement;
?
/**
* volatile用于保证数据的同步
* 可见性
* 粒度很小,只保证数据的同步
* 不保证原子性,可以避免指令重排!!!
* @since JDk 1.8
* @date 2021/6/22
* @author Lucifer
*/
public class VolatileTestNo1 {
?
/*加一个类变量*/
private volatile static int num = 0;
?
public static void main(String[] args) {
?
/*使用lambda表达式多线程操作变量*/
new Thread(() -> {
/*写一个死循环*/
while (num==0){
//这里不要编写代码--->目的是让cpu繁忙
}
}).start();
?
/*一秒后改变值为1*/
try {
Thread.sleep(1000);
}catch (InterruptedException e){
System.out.println(e.getMessage());
e.printStackTrace();
}
?
/*改变变量的值*/
num = 1;
?
}
/*
如果不加volatile那么线程不会停止
加了volatile以后一秒后num已经发生改变,虽然不会回显(因为事务没有回写到主存)但是线程一样会停止
保证数据的可见性,保证数据的重排
不保证赋值操作的原子性
*/
}
标签:image def vol -- 改变 interrupt 虚拟 com java学习
原文地址:https://www.cnblogs.com/JunkingBoy/p/14921548.html