是什么
volatile是Java虚拟机提供的轻量级的同步机制。
特性
- 保证可见性
- 不保证原子性
- 禁止指令重排
JMM是什么
可见性
原子性
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54/**
* @desc volatile可见性、非原子性验证
* @Author xw
* @Date 2019/8/19
*/
public class VolatileDemo {
public static void main(String[] args) {
// 验证可见性
seeOkVisibility();
// 验证非原子性
seeNonAtomic();
}
private static void seeNonAtomic() {
MyData myData = new MyData();
for (int i = 1; i <= 100; i++) {
new Thread(() -> {
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
for (int j = 1; j <= 100 ; j++) {
myData.addPlusPlus();
}
}, "T" + i).start();
}
while (Thread.activeCount() > 2) {
}
System.out.println(Thread.currentThread().getName() + "\t mission is over value:" + myData.number);
}
// 设置可见性
private static void seeOkVisibility() {
MyData myData = new MyData();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + "\t come in");
try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
myData.addTO60();
System.out.println(Thread.currentThread().getName() + "\t updated number value: " + myData.number);
}, "AAA").start();
while (myData.number == 0) {
}
System.out.println(Thread.currentThread().getName() + "\t mission is over");
}
}
class MyData {
volatile int number;
public void addTO60() {
this.number = 60;
}
public void addPlusPlus() {
this.number ++;
}
}
有序性
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
30
31
32/**
* @desc 指令重排
* @Author xw
* @Date 2019/8/8
*/
public class ReSortSeqDemo {
int a = 0;
boolean flag = false;
public void method01() {
a = 1;
flag = true;
}
// 多线程环境中线程交替执行,由于编译器优化重排的存在,两个线程中使用的变量能否保证一致性无法确定
// JDK7以后做了优化
public void method02() {
if (flag){
a = a + 5;
}
}
public static void main(String[] args) {
ReSortSeqDemo reSortSeqDemo = new ReSortSeqDemo();
for(int i = 1; i <= 100; i++) {
new Thread(() -> {
reSortSeqDemo.method01();
reSortSeqDemo.method02();
System.out.println(Thread.currentThread().getName() + " change number to " + reSortSeqDemo.a);
},"T" + i).start();
}
}
}
你在哪些地方用到过volatile?
单例模式DCL代码
1 | /** |