Skip to content

Commit 0bb5d6a

Browse files
author
leelovejava
committed
第三季 高并发
1 parent b6fada2 commit 0bb5d6a

File tree

6 files changed

+66
-0
lines changed

6 files changed

+66
-0
lines changed

docs/03/23.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# 23、能聊聊volatile关键字的原理吗?
2+
内存模型 -> 原子性、可见性、有序性 -> volatile
3+
4+
5+
6+
讲清楚volatile关键字,直接问你volatile关键字的理解,对前面的一些问题,这个时候你就应该自己去主动从内存模型开始讲起,原子性、可见性、有序性的理解,volatile关键字的原理
7+
8+
9+
10+
volatile关键字是用来解决可见性和有序性,在有些罕见的条件之下,可以有限的保证原子性,他主要不是用来保证原子性的
11+
12+
![volatile使用代码](images/23/01.png)
13+
14+
可见性,概念进行了加强和深化,volatile在可见性上的作用和原理,有一个很清晰的了解
15+
16+
17+
18+
在很多的开源中间件系统的源码里,大量的使用了volatile,每一个开源中间件系统,或者是大数据系统,都多线程并发,volatile
19+
20+
![kafka源码使用volatile](images/23/01.png)

docs/03/24.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# 24、你知道指令重排以及happens-before原则是什么吗?
2+
volatile关键字和有序性的关系,volatlie是如何保证有序性的,如何避免发生指令重排的
3+
4+
![volatile指令重排](images/24/01.png)
5+
6+
java中有一个`happens-before`原则:
7+
8+
编译器、指令器可能对代码重排序,乱排,要守一定的规则,happens-before原则,只要符合happens-before的原则,那么就不能胡乱重排,如果不符合这些规则的话,那就可以自己排序
9+
10+
* 1、程序次序规则:一个线程内,按照代码顺序,书写在前面的操作先行发生于书写在后面的操作
11+
12+
* 2、锁定规则:一个unLock操作先行发生于后面对同一个锁的lock操作,比如说在代码里有先对一个lock.lock(),lock.unlock(),lock.lock()
13+
14+
* 3、volatile变量规则:对一个volatile变量的写操作先行发生于后面对这个volatile变量的读操作,volatile变量写,再是读,必须保证是先写,再读
15+
16+
* 4、传递规则:如果操作A先行发生于操作B,而操作B又先行发生于操作C,则可以得出操作A先行发生于操作C
17+
18+
* 5、线程启动规则:Thread对象的start()方法先行发生于此线程的每个一个动作,thread.start(),thread.interrupt()
19+
20+
* 6、线程中断规则:对线程interrupt()方法的调用先行发生于被中断线程的代码检测到中断事件的发生
21+
22+
* 7、线程终结规则:线程中所有的操作都先行发生于线程的终止检测,我们可以通过Thread.join()方法结束、Thread.isAlive()的返回值手段检测到线程已经终止执行
23+
24+
* 8、对象终结规则:一个对象的初始化完成先行发生于他的finalize()方法的开始
25+
26+
27+
上面这8条原则的意思很显而易见,就是程序中的代码如果满足这个条件,就一定会按照这个规则来保证指令的顺序。
28+
29+
30+
31+
很多同学说:好像没听懂,模模糊糊,这些规则写的非常的拗口,晦涩难懂,在面试的时候比如面试官问你,happens-before原则,你必须把8条规则都背出来,反问,没有任何一个人可以随意把这个规则背出来的
32+
33+
规则制定了在一些特殊情况下,不允许编译器、指令器对你写的代码进行指令重排,必须保证你的代码的有序性
34+
35+
36+
但是如果没满足上面的规则,那么就可能会出现指令重排,就这个意思。
37+
38+
![volatile指令重排](images/24/02.png)
39+
40+
这8条原则是避免说出现乱七八糟扰乱秩序的指令重排,要求是这几个重要的场景下,比如是按照顺序来,但是8条规则之外,可以随意重排指令。
41+
42+
比如这个例子,如果用volatile来修饰flag变量,一定可以让prepare()指令在flag = true之前先执行,这就禁止了指令重排。
43+
44+
因为volatile要求的是,volatile前面的代码一定不能指令重排到volatile变量操作后面,volatile后面的代码也不能指令重排到volatile前面。
45+
46+
指令重排 -> happens-before -> volatile起到避免指令重排

docs/03/images/23/01.png

23.7 KB
Loading

docs/03/images/23/02.png

51.8 KB
Loading

docs/03/images/24/01.png

26 KB
Loading

docs/03/images/24/02.png

26.9 KB
Loading

0 commit comments

Comments
 (0)