1. volatile的作用
- 保证了可见性
- 不保证原子性
- 防止指令重排
2. 可见性的验证
class MyData{
volatile int number = 0;
public void addTo60(){
thie.number = 60;
}
}
public class VolatileDemo{
public static void main(String[] args) {
MyData myData = new MyData();
new Thread(()->{
try{TimeUnit.SECONDS.sleep(3);}catch(InterruptedException e){e.printStackTrace();}
myData.addTo60();
}, "AAA").start();
while(myData.number == 0) {
}
}
}
3. 不保证原子性的验证
class MyData{
volatile int number = 0;
public void addTo60(){
thie.number = 60;
}
public void addPlusPlus(){
number++;
}
AtomicInteger atomicInteger = new AtomicInteger();
public void addMyAtomic(){
atomicInteger.getAndIncrement();
}
}
public class VolatileDemo{
public static void main(String[] args) {
MyData myData = new MyData();
for(int i = 0; i < 20; i++) {
new Thread(() -> {
for(int j = 1; j <= 1000; j++){
myData.addPlusPlus();
myData.addMyAtomic();
}
}, String.valueOf(i)).start();
}
while(Thread.activeCount() > 2) {
Thead.yield();
}
System.out.println(myData.number);
System.out.println(myData.atomicInteger );
}
}
4. 防止指令重排
- 指令重排概念:计算机在执行程序时,为了提高性能,编译器和处理器会对指令做重排。
源代码 ----> 编译器优化的重排 ----> 指令并行的重排 ----> 内存系统的重排 ----> 最终执行的指令 - 案例1:
public void mySort(){
int x = 11;
int y = 12;
x = x + 5;
y = x * x;
}
- 案例2:
int a, b, x, y = 0;
x = a; b = 1;
y = b; a = 2;
b = 1; x = a;
a = 2; y = b;