hooyantsing's Blog

31_Volatile可见性及非原子性验证

字数统计: 313阅读时长: 1 min
2020/08/28

31 Volatile可见性及非原子性验证

狂神说Java JUC并发编程最新版通俗易懂

Volatile 的认识

  1. 保证可见性
  2. 不保证原子性
  3. 禁止指令重排

    原子性

原子性:某个时刻,只有一个线程能够执行一段代码,这段代码通过一个 monitor object 保护。

Java代码 mun++ 看着是一行代码,实际上是多步操作。

通过解析字节码文件,可以看到 mun++ 对应的操作:

使用条件,应用场景

  • 对变量的写操作不依赖于当前值。(也就是通过其他的变量来生成 volatile变量的值,而不是通过volatile值来生成volatile值)
  • 该变量没有包含在具有其他变量的不变式中。

    案例

验证 volatile 的不保证原子性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package tvolatile;

public class Demo02 {

private volatile static int num = 0;

public static void add(){
num++;
}

public static void main(String[] args) {
// 理论上num应该等于20000
for (int i = 0; i < 20; i++) {
new Thread(
() -> {
for (int i1 = 0; i1 < 1000; i1++) {
add();
}
}
).start();
}

// 保证除了 main 和 gc 以外的线程均执行完毕
if(Thread.activeCount() > 2){
Thread.yield();
}
System.out.println(num);
}
}

运行结果:

17765

出现了线程不安全问题。

CATALOG
  1. 1. 31 Volatile可见性及非原子性验证
    1. 1.0.1. Volatile 的认识
    2. 1.0.2. 原子性
    3. 1.0.3. 使用条件,应用场景
    4. 1.0.4. 案例