6.22Java多线程volitale
volitale说明
作用:
保证线程间变量的可见性(注意:不是线程之间的变量可见)
线程A对变量X进行修改后,在线程A后面执行的其他线程能看到变量X的变动。
需要符合以下两个规则:
-
线程对变量进行修改之后要立刻写回到主内存--->防止主内存与工作内存中不一致的情况
-
加了volitale修饰,对变量的修改就会立刻写到主内存当中
-
同时通知另一个线程拿到最新的
-
-
线程对变量读取的时候要从主内存中读,而不是从缓存中读
线程工作模式图:
特点:
-
各线程的工作内存间彼此独立、互不可见。
-
在线程启动的时候,虚拟机为每个内存分配一块工作内存。
-
包含了线程内部定义的局部变量
-
线程所需要使用的共享变量(非线程内构造的对象)的副本
-
volatile的缺陷:--->只保证了同步的数据可见
volatile不能保证原子性
什么是原子性?
以代码a++举例,在汇编层面会分成三步
-
拿到a
-
a+1计算结果
-
存储计算的结果到a中
这完整的三步是一个整体、一个变量。--->volatile不能保证这三个作为一个整体发生变化
volatile实例demo
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已经发生改变,虽然不会回显(因为事务没有回写到主存)但是线程一样会停止
保证数据的可见性,保证数据的重排
不保证赋值操作的原子性
*/
}
It's a lonely road!!!