Volatile
是什么:
- jvm提供的轻量级的同步机制
特性
- 可见性
- 不保证原子性
- 禁止指令重排性
JMM
- Java内存模型,是一种规则和规范,并不实际存在
- 特点:可见性 原子性 有序性
可见性:
- 当多个线程操作一个对象时,每个线程都有自己独立的储存空间,如果使用volatile,则可以使一个线程修改公共资源,其他对象也可以知道。
- 有的jdk版本不加volatile其实也带有可见性
- 可见性修改是指 有一个主内存 然后进来多个线程,每个线程拷贝一份主内存的数据,然后在自己的工作内存中进行修改,修改好了直接替换掉主内存中原有的数据,而其他线程也会知道数据已经被修改。
public class volatile_learn {
public static void main(String[] args) {
Person alan = new Person();
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" come in");
try {
Thread.sleep(1000);
} catch (Exception e) {
//TODO: handle exception
}
alan.add();
System.out.println(Thread.currentThread().getName()+": "+alan.age);
},"A").start();
try {
Thread.sleep(2000);
} catch (Exception e) {
//TODO: handle exception
}
System.out.println(Thread.currentThread().getName()+" :"+alan.age);
}
}
class Person{
volatile int age;
public void add() {
age = 10;
}
public void delete() {
age = 5;
}
}
不保证原子性
-
原子性解决方案
- sychronize
- AtomicRefference
禁止指令重排
-
什么意思:
-
我们正常写代码的顺序 可能和 编译器执行代码 的顺序不同,但是底层还是遵守数据依赖性的,也就是先定义,而后面的赋值则顺序可能被重排,这会影响线程的安全性。
-
就好比我们看一本书,书的目录和整体结构都是事先定义好的,但我们可能有的地方看不懂,则进行跳跃式阅读,找自己读起来容易的地方先读,这就是底层进行指令重排的目的,先执行简单的。
-
使用volatile可以保证编译不重排,解决指令重排导致的可见性问题和有序性问题。
-