zoukankan      html  css  js  c++  java
  • Java内存模型(JMM)中的happens-before

      happens-before是JMM中最核心的概念,对于Java程序员来说,理解happens-before是理解JMM的关键 。

    1.JMM的设计

      首先,来看看JMM的设计意图。从JMM的设计者的角度,在设计JMM时,需要考虑两个关键因素。

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

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

      由于这两个因素互相矛盾,所以JSR-133专家组在设计JMM时的核心目标就是找到一个好 的平衡点:一方面,要为程序员提供足够强的内存可见性保证;另一方面,对编译器和处理器的限制要尽可能地放松。下面让我们来看看JSR-133是如何实现这一目标的。

      

    double pi = 3.14 ;      //A
    double r = 1.0 ;         //B
    double area= pi*r*r; //C

      上面计算圆的面积的示例代码存在3个happens-before关系如下 :

      (1)A happens-before B

      (2)B happens-before C

      (3)A happens-before C

      在3个happens-before关系中,2和3是必须的,但1是不必要的。因此,JMM把happens-before 要求禁止的重排序分为了下面两类 :

      □ 会改变程序执行结果的重排序。

      □ 不会改变程序执行结果的重排序。

      JMM对这两种不同性质的重排序,采取了不同的策略,如下:

      □ 对于会改变程序执行结果的重排序,JMM要求编译器和处理器必须禁止这种重排序。

      □ 对于不会改变程序执行结果的重排序,JMM对编译器和处理器不做要求(JMM允许这种重排序) 。

      下图是JMM的设计示意图:

      从上图可以看出两点,如下。

      □ JMM向程序员提供的happens-before规则能满足程序员的需求。JMM的happens-before 规则不但简单易懂,而且也向程序员提供了足够强的内存可见性保证(有些内存可见性保证并不一定真是存在,比如上面的A happens-before B) 。

      □ JMM对编译器和处理器的束缚已经尽可能少。从上面的分析可以看出,JMM其实是在遵循一个基本原则:只要不改变程序的执行结果(指的是单线程程序和正确同步的多线程程序),编译器和处理器怎么优化都行。例如,如果编译器经过细致的分析后,认定一个锁只会被单个线程访问,那么这个锁可以被消除。再如,如果编译器经过细致分析后,认定一个volatile变量只会被单个线程访问,那么编译器可以把这个volatile变量当做是一个普通变量来对待。这些优化既不会改变程序的执行结果,又能提高程序的执行效率。

    2.happens-before的定义

      

      

      

  • 相关阅读:
    Android Media Playback 中的MediaPlayer的用法及注意事项(二)
    Android Media Playback 中的MediaPlayer的用法及注意事项(一)
    34. Search for a Range
    33. Search in Rotated Sorted Array
    32. Longest Valid Parentheses
    31. Next Permutation下一个排列
    30. Substring with Concatenation of All Words找出串联所有词的子串
    29. Divide Two Integers
    28. Implement strStr()子串匹配
    27. Remove Element
  • 原文地址:https://www.cnblogs.com/dquery/p/7004379.html
Copyright © 2011-2022 走看看