1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > JAVA并发编程基础:JVM内存模型详解(附阿里高频面试题)

JAVA并发编程基础:JVM内存模型详解(附阿里高频面试题)

时间:2022-07-18 20:56:02

相关推荐

JAVA并发编程基础:JVM内存模型详解(附阿里高频面试题)

前面两个章节我们分享了并发问题产生的根源以及CPU和操作系统提供的解决方案;

通常来讲JVM是运行在操作系统之上,但它本身是一个虚拟机,是可以运行在硬件之上并且提供了一套完备的运行机制,其中就包含了内存模型的定义。

内存模型是什么?

JVM内存模型有两种含义,一种是众所周知的JVM内存的划分,分为了堆、栈、方法区、程序计数器,其中堆又被划分为了新生代和老年代,栈分为虚拟机栈和本地方法栈;堆和方法区是线程共享的,栈和程序计数器是线程私有的。(这里先不细说了,我们将在JVM专题中详细讲解)

内存模型的另一种含义指的是针对前面章节中提到的“数据可见性和缓存一致性”问题而定义的一系列保障程序可以并发并且正常执行的逻辑规则。我们只要合理的运用这些规则和机制,就可以避免并发带来的问题。这一系列规则也就是我们通常说的 “happens-before”规则。

什么是happens-before规则?

通过专栏第一讲的分析,我们知道造成并发问题的根源之一是数据的可见性,举例来说就是CPU1的操作结果不能够及时的被CPU2所知道,CPU2使用了比较旧的数据或者是错误的数据进行运算,最终导致逻辑问题。

happens-before规则就是定义了一系列规则,满足这些规则的时候,先发生的操作的结果一定会被后发生的操作所看到;

happens-before规则如下:(除了规则1之外,其他规则主要是为了解决多线程问题的,所以在思考理解的时候,两个操作要理解为在两个线程中的操作)

1.同一个线程内部,各个操作之间的关系满足happens - before

也就是说在一个线程中,先执行的操作的结果可以被后执行的操作看到;举一个例子,A操作修改了变量a的值,同一个线程中的B操作如果发生在A操作之后,那么B一定可以看到修改之后的值。

但如果B操作发生在另一个线程,则不一定能看到修改后的值。

2.volatile变量的写操作happens-before读操作

对于volatile变量,如果一个写操作发生在读操作之前,那么读操作一定可以看到写操作之后的值。无论读写两个操作是否在一个线程中;

3.解锁操作happens-before加锁操作

解锁操作发生在加锁操作之前,那么加锁操作一定可以看到解锁操作的结果。

本条规则结合规则1和后面的规则7(传递性),就可以正确的完成线程之间的操作可见性。

4.对象构建完成,happens-before finalize操作

对象构建完成的操作(初始化操作)发生在析构之前,那么析构操作一定可以看到初始化的结果。

5.线程的启动,线程的操作,线程终止

这三个操作由happens-before关系,具体来说就是start操作happens线程内的所有操作,线程内的操作happens-before终止操作(比如Thread.join操作,具体含义后面的章节中讲解);

也就是后面的操作一定可以看到前面操作的结果。

6.线程中断的happen-before原则:

对线程interrupt()方法的调用先行发生于被中断线程代码检测到中断事件的发生(可以通过Thread.interrupted()检测到是否发生中断。)

7.传递性规则

如果A操作 happen-before B操作,B操作happen-before C操作,那么A操作happen-before C操作。

踩坑面试题

这里可能的情况有很多,下面来一一分析:

第一种可能,r1 和 r2都等于0;method1和method2同时执行,分别在第4行和第9行之后中断。

第二种可能,r2 = 0, r1 = 1;先执行method1,后执行method2;

第三种可能,r1 = 0, r2 = 2;先执行method2,后执行method1;

第四种可能,r1 = 1, r2 = 2; 在实际执行时,发生了指令重排序,第4行和第5行交换了位置,第9行和第10行交换了位置;

第五种可能,r1 = 1,r2 = 0;在实际执行时,发生了指令重排序,第4行和第5行交换了位置;结合第一种可能的原因就会得到这个结果。

第六种可能,r1 = 0,r2 = 2;在实际执行时,发生了指令重排序,第9行和第10行交换了位置;结合第一种可能的原因就会得到这个结果。

如果要解决第四、五、六这三种看起来比较诡异的情况,只需要防止指令重排序即可;前面章节已经讲过,Java防止指令重排序的方案是将变量声明volatile。

为什么声明为volatile可以防止重排序,原理是什么,我们将在volatile关键字章节进行讲解。

感谢您的阅读,喜欢请点赞、关注、转发;

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。