java内存模型:解决可见性和有序性问题

在并发场景中,因可见性、原子性、有序性导致的问题常常会违背我们的直觉,从而成为并发编程的 Bug 之源。

其中java内存模型用于解决可见性和有序性的问题。

为什么定义Java内存模型?现代计算机体系大部是采用的对称多处理器的体系架构。每个处理器均有独立的寄存器组和缓存,多个处理器可同时执行同一进程中的不同线程,这里称为处理器的乱序执行。在Java中,不同的线程可能访问同一个共享或共享变量。如果任由编译器或处理器对这些访问进行优化的话,很有可能出现无法想象的问题,这里称为编译器的重排序。除了处理器的乱序执行、编译器的重排序,还有内存系统的重排序。因此Java语言规范引入了Java内存模型,通过定义多项规则对编译器和处理器进行限制,主要是针对可见性和有序性。

java内存模型是个很复杂的规范,本质上可以理解为,java内存模型规范了JVM如何提供按需禁用缓存和编译优化的方法。这些方法包括:volatile、synchronized和fanal三个关键字,以及Happens-Before规则。其中Happens-Before规则表达的是:前面一个操作的结果对后续操作是可见的。Happens-Before约束了编译器的优化行为。虽然允许编译器优化,但是要求编译器优化后一定遵守Happens-Before规则。

Java内存模型底层怎么实现的?主要是通过内存屏障(memory barrier)禁止重排序的,即时编译器根据具体的底层体系架构,将这些内存屏障替换成具体的 CPU 指令。对于编译器而言,内存屏障将限制它所能做的重排序优化。而对于处理器而言,内存屏障将会导致缓存的刷新操作。比如,对于volatile,编译器将在volatile字段的读写操作前后各插入一些内存屏障。

在并发场景中,因可见性、原子性、有序性导致的问题常常会违背我们的直觉,从而成为并发编程的 Bug 之源。这三者在编程领域属于共性问题

猜你喜欢

转载自www.cnblogs.com/gao1991/p/12099777.html
今日推荐