File tree 2 files changed +69
-0
lines changed
src/main/java/com/crossoverjie/concurrent
2 files changed +69
-0
lines changed Original file line number Diff line number Diff line change 1
1
# 你应该知道的 volatile
2
2
3
+ ## 前言
4
+
5
+ 不管是在面试,还是实际开发中 ` volatile ` 都是一个应该掌握的技能。
6
+
7
+ 首先来看看为什么会出现这个关键字。
8
+
9
+ ## 内存可见性
10
+ 由于 Java 内存模型(JMM)规定,所有的变量都存放在主内存中,而每个线程都有着自己的工作内存(高速缓存)。
11
+
12
+ 线程在工作时,需要将主内存中的数据拷贝到工作内存中。这样对数据的任何操作都是基于工作内存的(效率提高),不能直接操作主内存以及其他线程工作内存中的数据,之后再将更新之后的数据刷新到主内存中。
13
+
14
+ > 这里所提到的主内存可以简单认为是** 堆内存** ,而工作内存则可以认为是** 栈内存** 。
15
+
16
+ 如下图所示:
17
+
18
+ ![ ] ( https://ws2.sinaimg.cn/large/006tKfTcly1fmouu3fpokj31ae0osjt1.jpg )
19
+
20
+ 所以在并发运行时会出现线程 B 所读取到的数据是线程 A 更新之前的数据。
21
+
22
+ 显然这肯定是会出问题的,因此 ` volatile ` 的作用出现了:
23
+
24
+ > 当一个变量被 ` volatile ` 修饰时,任何线程对它的写操作都会立即刷新到主内存中,并且会强制让缓存了该变量的线程中的数据清空,必须从主内存重新读取最新数据。
25
+
26
+ ### 内存可见性的应用
27
+
28
+
29
+ ## 指令重排
30
+
31
+ ### 指令重排的的应用
Original file line number Diff line number Diff line change
1
+ package com .crossoverjie .concurrent ;
2
+
3
+ import java .util .concurrent .TimeUnit ;
4
+
5
+ /**
6
+ * Function:
7
+ *
8
+ * @author crossoverJie
9
+ * Date: 09/03/2018 00:09
10
+ * @since JDK 1.8
11
+ */
12
+ public class Volatile implements Runnable {
13
+
14
+ private static volatile boolean flag = true ;
15
+
16
+ @ Override
17
+ public void run () {
18
+ while (flag ){
19
+ System .out .println (Thread .currentThread ().getName () + "正在运行。。。" );
20
+ }
21
+ System .out .println (Thread .currentThread ().getName () +"执行完毕" );
22
+ }
23
+
24
+ public static void main (String [] args ) throws InterruptedException {
25
+ Volatile aVolatile = new Volatile ();
26
+ new Thread (aVolatile ,"thread A" ).start ();
27
+
28
+
29
+ System .out .println ("main 线程正在运行" ) ;
30
+
31
+ TimeUnit .MILLISECONDS .sleep (100 ) ;
32
+
33
+ aVolatile .stopThread ();
34
+
35
+ }
36
+
37
+ private void stopThread (){
38
+ flag = false ;
39
+ }
40
+ }
You can’t perform that action at this time.
0 commit comments