Java语言提供了一种稍弱的同步机制,即volatile变量,用来确保将变量的更新操作通知到其他线程。当 把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操 作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此 在读取volatile类型的变量时总会返回最新写入的值。
在访问volatile变量时不会执行加锁操作,因此也就不会使执行线程阻塞,因此volatile变量是一种比 sychronized关键字更轻量级的同步机制。
可以理解为当一个变量前面有volatile修饰的时候,他每次的取值不会从自身的栈内存中取,而是会到主内存去取。但是却不会关注主内存数值的变化。 使用synchronized还是使用volatile根据自身业务就好。
我们看一个简单的小例子,代码如下。
package com.cn;
public class Volatile {
public static void main(String[] args) {
Desk desk = new Desk(1, "宜家", 2000);
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
//修改价格
System.out.println("Hello15Volatile.main" + i);
desk.setPrice(i);
}
}).start();
new Thread(() -> {
for (int i = 0; i < 1000; i++) {
//修改价格
System.out.println(desk.getPrice() + "----" + i);
}
}).start();
;
}
}
class Desk {
private int id;
private String name;
//价格是灵活调控的
private volatile int price;
public Desk(int id, String name, int price) {
this.id = id;
this.name = name;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
这里创建了两个线程,一个修改价格,一个获取价格,大家运行后就会发现volatile的特性。
volatile的性能:是内部防止了代码重排,有一个内存屏障,大家了解一下。
看这张图 我们解析一下上面的代码
这样每次getPrice就会重新去主内存中取,而不会用自己的栈内存,因为自身又是弱同步机制,所以也不会影响主内存的运行。



