1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      JMM指令重排序的示例分析

      這篇文章給大家分享的是有關(guān)JMM指令重排序的示例分析的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

      成都創(chuàng)新互聯(lián)10多年成都企業(yè)網(wǎng)站建設(shè)服務(wù);為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁設(shè)計及高端網(wǎng)站定制服務(wù),成都企業(yè)網(wǎng)站建設(shè)及推廣,對成都宣傳片制作等多個行業(yè)擁有多年的營銷推廣經(jīng)驗的網(wǎng)站建設(shè)公司。

      一、指令為什么要重排序?

      在計算機(jī)系統(tǒng)中,指令為了更快的完成結(jié)果,會根據(jù)邏輯關(guān)系、指令大小進(jìn)行重排序,以達(dá)到超流水線的效果,但在代碼執(zhí)行完后,保證結(jié)果輸出是一致的。

      在JVM中又兩條原則:

      • as-if -serials         這個規(guī)則適用于單線程,默認(rèn)自動處理

      • happens-before   這個規(guī)則適用于多線程,當(dāng)然也要通過相應(yīng)的鎖和關(guān)鍵字來實現(xiàn)

      二、JMM(Java Memory Manager)指令重排序如何實現(xiàn)的呢?

      我們知道,JIT會根據(jù)CPU架構(gòu)編譯合適的代碼去執(zhí)行,因此,在匯編層面討論反而不見得能統(tǒng)一意見,比如X86,他只有l(wèi)ock來實現(xiàn),其他CPU架構(gòu)則是LoadLoad,StoreStore,LoadStore,StoreLoad

      實際上我們還是在JIT層面思考比較容易理解,這里我們定義一個類

      (注意:這個類未必和JIT實際效果一致,取決于JIT激進(jìn)程度)

      package com.apptest;
      
      public class VolatileWatcher {
      
          private String A;
          private String B;
          private String C;
          private String D;
          private String E;
      
          public void run() {
              String a = "a";
              String b = "b";
              String c = "c";
              String d = "d";
              String e = "e";
              A = a;
              B = b;
              C = c;
              D = d;
              E = e;
      
              System.out.println(A);
              System.out.println(B);
              System.out.println(C);
              System.out.println(D);
              System.out.println(E);
          }
      }

      那么如果重排序,效果可能如下

      package com.apptest;
      
      public class VolatileWatcher {
      
          private String A;
          private String B;
          private String C;
          private String D;
          private String E;
      
       
          public void run() {
              String a = "a";
              String b = "b";
              String c = "c";
              String d = "d";
              String e = "e";
      
              A = a;
              System.out.println(A);
      
              B = b;
              System.out.println(B);
      
              C = c;
              System.out.println(C);
              D = d;
              System.out.println(D);
      
              E = e;
              System.out.println(E);
          }
      }

      這是JIT可能重排序后的結(jié)果,實際上寄存器、CPU也會進(jìn)行重排序,但最終也會保證內(nèi)存一致性。

      三、如何禁止指令重排序呢?

      Java中,禁止指令重排序的關(guān)鍵字只有2個,一個是volatile、另一個是final,某種成都上,也能說明final和volatile不能同時修飾一個變量的原因,因為他們的功能有些重疊。

      3 .1  要不要禁止

      首先要確定要不要禁止重排序,重排序往往在多線程中出現(xiàn)問題,如果程序在串行執(zhí)行,完全沒有必要,因此,單線程中的引用類型(不包括常量和字符串常量,這些類型引用建議加final)建議不要加final和volatile,當(dāng)然,final需要考慮深入一些,因為有時我們需要做一些強(qiáng)約束,但總體來說能不加就不加。

      3.2 原理

      多線程中,維護(hù)hanpens-before原則不是JVM自身就能處理的,還需要在代碼層面進(jìn)行相應(yīng)的指示,此外,相應(yīng)的JIT會將指示編譯成指令,讓寄存器和CPU也遵守。

      指令重排序的達(dá)到的最終效果

      讀操作

      JMM指令重排序的示例分析

      寫操作

      JMM指令重排序的示例分析

      3.3 效果演示

      回到文章開頭,我們給VolatileWatcher的C變量添加volatile修飾,那么JIT重排序后的結(jié)果可能是如下情況

      public class VolatileWatcher {
      
          private String A;
          private String B;
          private volatile String C;
          private String D;
          private String E;
      
          public void run() {
              String a = "a";
              String b = "b";
              String c = "c";
              String d = "d";
              String e = "e";
              B = b;
              A = a;
              C = c; //寫屏障
              E = e;
              D = d;
      
              System.out.println(A);
              System.out.println(B);
              System.out.println(C); //讀屏障
              System.out.println(D);
              System.out.println(E);
          }
      }

      我們發(fā)現(xiàn),A、B不能跨越C變量的寫屏障往下重排序,但是屏障上方的A、B之間也是可以重排序的,E、D不能跨越讀屏障,但是E、D可以在讀屏障和寫屏障之間排序。(這里故意寫成A,B,E,D在屏障外順序變化,目的主要是為了說明屏障的作用,具體看實際效果)

      四、final和volatile的區(qū)別?

      我們知道,final修飾的是只讀變量,有很強(qiáng)的“只讀”約束性,所有final修飾的變量都需要在構(gòu)造方法中初始化(類外部final字段的最終會插入到super(...)之后 ),而volatile一般用于多線程變量的讀寫,但他們都具備實現(xiàn)內(nèi)存屏障的能力,可以說,都能實現(xiàn)禁止重排序。

      不同點(diǎn):

      final字段的寫操作,只作用于構(gòu)造函數(shù)。

      final字段的讀操作,讀取和volatile基本一樣

      感謝各位的閱讀!關(guān)于“JMM指令重排序的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!


      新聞名稱:JMM指令重排序的示例分析
      鏈接地址:http://www.ef60e0e.cn/article/pgghgc.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        麻江县| 晋中市| 昌邑市| 揭阳市| 永和县| 焉耆| 靖江市| 临沧市| 安陆市| 密云县| 伊金霍洛旗| 安丘市| 武隆县| 乐东| 富锦市| 永济市| 信丰县| 沙洋县| 九江县| 乐昌市| 永寿县| 保康县| 广西| 海晏县| 泗洪县| 武宁县| 周口市| 堆龙德庆县| 叙永县| 满城县| 沂水县| 通城县| 深水埗区| 常山县| 平原县| 正宁县| 大邑县| 中山市| 建瓯市| 凤山县| 揭阳市|