JMM(内存模型)

来源:互联网 发布:淘宝网的收入来源 编辑:程序博客网 时间:2024/05/16 12:29

1、JMM(Java Memory Model)Java内存模型,其主要的作用是围绕着在并发处理过程中如何处理可见性、原子性、有序性这三个特性而建立的模型。

(1).可见性:在JMM中提供了Volatile、final、synchronized块来保证可见性。

主要是针对两个或多个线程同时共享变量时一个线程操作变量后的结果对于另一个线程来说是可见的。所谓的可见性,其实就是获取的结果没有歧义性。

(2).有序性:这个概念是相对,如果在本线程内,所有操作都是有序的,如果在另一个线程观察另一个线程,所有的操作 都是无序的。

这其中其实涉及基本不同的知识点,如果在一个线程观察另一个线程,所有的操作都是无序的,前句是“线程内表现为串行”后句表现为“指令的重排序”和“工作 内存和主存同步延迟”现象。

(3).重排序:JMM在执行程序时为了提高性能,编译器和处理器通常会对程序的指令进行重排序,就是因为这些重排序,导致了多线程内存可见性问题。


在设计JMM时,需要考虑两个主要的因素:

(1).程序员对内存模型的使用。程序员希望内存模型易于理解、易于编程。程序员希望基于一个强大的内存模型来编写代码。

(2).编译器和处理器对内存模型的实现。编译器和处理希望内存模型对于它们的束缚越少越好,这样它们就可以做尽可能多的优化提高性能。编译器和处理器希望实现一弱内存模型。

其实以上的两点是矛盾的,所以在设计JMM核心目标的时候,找到一个平衡点是很重要的。一方面,要为程序员提供足够强大的JMM,另一方面,对编译器和处理器的限制要尽可能地放松。



对于happens-before 的定义如下:

(1).如果一个操作happens-before 另一个操作,那么第一个操作的执行结果将对第二个操作可见,而且第一个操作的执行顺序排在第二个操作之前。

(2).两个操作之间存在happens-before关系,并不意味着Java平台的具体实现必须要照happens-before关系来执行。如果重排序之后的执行结果,与按happens-before关系来执行的结果一致,那么这种重排序并不非法。


其中(1)只是JMM对程序员的承诺,实际的执行结果有时可能并不是这样的。

其中(2)是JMM对编译器和处理的重排序的约束原则。JMM其实只遵循一个基本的原则:只要不改变程序的执行结果(指的是单线程程序和正确同步的多线程序),编译器和处理器怎么优化都行的。


其实本质上as-if-serial本质上一样的:

as-if-serial语义是:不管怎么重排序(编译器和处理器为了提高并行效率),(单线程)线程的执行结果不能被改变。编译器,runtime和处理器都必须遵循as-if-serial原则。



happens-before:定义了如下几个规则:

(1).程序顺序规则:一个线程的每个操作,happens-before于该线程中的任意后续操作。

(2).监视器规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。

(3).volatile变量规则:对一个volatile域的写,happens-before于任意后续对这个volatile域的读。

(4).传递性:如果A happens-before B,且B happens-before C,那么A happens-before C.

0 0
原创粉丝点击