<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 12, comments - 8, trackbacks - 0, articles - 5
      BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理
    JMM規(guī)范: 

    The rules for happens-before are: 


    Program order rule. Each action in a thread happens-before every action in that thread that comes later in the program order. 



    Monitor lock rule. An unlock on a monitor lock happens-before every subsequent lock on that same monitor lock. 



    Volatile variable rule. A write to a volatile field happens-before every subsequent read of that same field. 



    Thread start rule. A call to Thread.start on a thread happens-before every action in the started thread. 



    Thread termination rule. Any action in a thread happens-before any other thread detects that thread has terminated, either by successfully return from Thread.join or by Thread.isAlive returning false. 



    Interruption rule. A thread calling interrupt on another thread happens-before the interrupted thread detects the interrupt (either by having InterruptedException tHRown, or invoking isInterrupted or interrupted). 



    Finalizer rule. The end of a constructor for an object happens-before the start of the finalizer for that object. 



    Transitivity. If A happens-before B, and B happens-before C, then A happens-before C. 


    appens-before完整規(guī)則:

    (1)同一個(gè)線程中的每個(gè)Action都happens-before于出現(xiàn)在其后的任何一個(gè)Action。

    (2)對(duì)一個(gè)監(jiān)視器的解鎖happens-before于每一個(gè)后續(xù)對(duì)同一個(gè)監(jiān)視器的加鎖。

    (3)對(duì)volatile字段的寫(xiě)入操作happens-before于每一個(gè)后續(xù)的同一個(gè)字段的讀操作。

    (4)Thread.start()的調(diào)用會(huì)happens-before于啟動(dòng)線程里面的動(dòng)作。

    (5)Thread中的所有動(dòng)作都happens-before于其他線程檢查到此線程結(jié)束或者Thread.join()中返回或者Thread.isAlive()==false。

    (6)一個(gè)線程A調(diào)用另一個(gè)另一個(gè)線程B的interrupt()都happens-before于線程A發(fā)現(xiàn)B被A中斷(B拋出異常或者A檢測(cè)到B的isInterrupted()或者interrupted())。

    (7)一個(gè)對(duì)象構(gòu)造函數(shù)的結(jié)束happens-before與該對(duì)象的finalizer的開(kāi)始

    (8)如果A動(dòng)作happens-before于B動(dòng)作,而B(niǎo)動(dòng)作happens-before與C動(dòng)作,那么A動(dòng)作happens-before于C動(dòng)作。



    ---------------------------- 


    什么是happens-before? 
    happens-before就是“什么什么一定在什么什么之前運(yùn)行”,也就是保證順序性。 
    因?yàn)镃PU是可以不按我們寫(xiě)代碼的順序執(zhí)行內(nèi)存的存取過(guò)程的,也就是指令會(huì)亂序或并行運(yùn)行, 
    只有上面的happens-before所規(guī)定的情況下,才保證順序性。 
    如: 
    Java代碼 
    1. public class Test {  
    2.   
    3.     private int a = 0;  
    4.   
    5.     private long b = 0;  
    6.   
    7.     public void set() {  
    8.         a = 1;  
    9.         b = -1;  
    10.     }  
    11.   
    12.     public void check() {  
    13.         if (! ((b == 0) || (b == -1 && a == 1))  
    14.             throw new Exception("check Error!");  
    15.     }  
    16. }  

    對(duì)于set()方法的執(zhí)行: 
    1. 編譯器可以重新安排語(yǔ)句的執(zhí)行順序,這樣b就可以在a之前賦值。如果方法是內(nèi)嵌的(inline),編譯器還可以把其它語(yǔ)句重新排序。 
    2. 處理器可以改變這些語(yǔ)句的機(jī)器指令的執(zhí)行順序,甚到同時(shí)執(zhí)行這些語(yǔ)句。 
    3. 存儲(chǔ)系統(tǒng)(由于被緩存控制單元控制)也可以重新安排對(duì)應(yīng)存儲(chǔ)單元的寫(xiě)操作順序,這些寫(xiě)操作可能與其他計(jì)算和存儲(chǔ)操作同時(shí)發(fā)生。 
    4. 編譯器,處理器和存儲(chǔ)系統(tǒng)都可以把這兩條語(yǔ)句的機(jī)器指令交叉執(zhí)行。 
    例如:在一臺(tái)32位的機(jī)器上,可以先寫(xiě)b的高位,然后寫(xiě)a,最后寫(xiě)b的低位,(注:b為long類型,在32位的機(jī)器上分高低位存儲(chǔ)) 
    5. 編譯器,處理器和存儲(chǔ)系統(tǒng)都可以使對(duì)應(yīng)于變量的存儲(chǔ)單元一直保留著原來(lái)的值, 
    以某種方式維護(hù)相應(yīng)的值(例如,在CPU的寄存器中)以保證代碼正常運(yùn)行,直到下一個(gè)check調(diào)用才更新。 
    ... 
    在單線程(或同步)的情況下,上面的check()永遠(yuǎn)不會(huì)報(bào)錯(cuò), 
    但非同步多線程運(yùn)行時(shí)卻很有可能。 


    并且,多個(gè)CPU之間的緩存也不保證實(shí)時(shí)同步, 
    也就是說(shuō)你剛給一個(gè)變量賦值,另一個(gè)線程立即獲取它的值,可能拿到的卻是舊值(或null), 
    因?yàn)閮蓚€(gè)線程在不同的CPU執(zhí)行,它們看到的緩存值不一樣, 
    只有在synchronized或volatile或final的性況下才能保證正確性, 
    很多人用synchronized時(shí)只記得有l(wèi)ock的功能,而忘記了線程間的可見(jiàn)性問(wèn)題。 
    如: 
    Java代碼 
    1. public class Test {  
    2.   
    3.     private int n;  
    4.   
    5.     public void set(int n) {  
    6.         this.n = n;  
    7.     }  
    8.   
    9.     public void check() {  
    10.         if (n != n)  
    11.             throw new Exception("check Error!");  
    12.     }  
    13. }  

    check()中的 n != n 好像永遠(yuǎn)不會(huì)成立,因?yàn)樗麄冎赶蛲粋€(gè)值,但非同步時(shí)卻很有可能發(fā)生。 

    另外,JMM不保證創(chuàng)建過(guò)程的原子性,讀寫(xiě)并發(fā)時(shí),可能看到不完整的對(duì)象, 
    這也是為什么單例模式中著名的"雙重檢查成例"方法,在Java中行不通。(但.Net的內(nèi)存模型保證這一點(diǎn)) 
    當(dāng)然,在Java中單例的延遲加載可以用另一種方案實(shí)現(xiàn)(方案四): 

    方案一:非延遲加載單例類 
    Java代碼 
    1. public class Singleton {  
    2.   
    3.   private Singleton(){}  
    4.   
    5.   private static final Singleton instance = new Singleton();  
    6.   
    7.   public static Singleton getInstance() {  
    8.     return instance;     
    9.   }   
    10. }  


    方案二:簡(jiǎn)單的同步延遲加載 
    Java代碼 
    1. public class Singleton {   
    2.   
    3.   private static Singleton instance = null;  
    4.   
    5.   public static synchronized Singleton getInstance() {  
    6.     if (instance == null)  
    7.       instance = new Singleton();  
    8.     return instance;     
    9.   }   
    10.   
    11. }   


    方案三:雙重檢查成例延遲加載 
    目的是避開(kāi)過(guò)多的同步, 
    但在Java中行不通,因?yàn)橥綁K外面的if (instance == null)可能看到已存在,但不完整的實(shí)例。 
    JDK5.0以后版本若instance為volatile則可行 
    Java代碼 
    1. public class Singleton {   
    2.   
    3.   private static Singleton instance = null;  
    4.   
    5.   public static Singleton getInstance() {  
    6.     if (instance == null) {  
    7.         synchronized (Singleton.class) {  
    8.             if (instance == null) {  
    9.                 instance = new Singleton();  
    10.             }  
    11.         }  
    12.     }  
    13.     return instance;     
    14.   }   
    15.   
    16. }   


    方案四:類加載器延遲加載 
    Java代碼 
    1. public class Singleton {   
    2.   
    3.   private static class Holder {  
    4.     static final Singleton instance = new Singleton();  
    5.   }  
    6.   
    7.   public static Singleton getInstance() {  
    8.     return Holder.instance;     
    9.   }   
    10.   
    11. }   

    主站蜘蛛池模板: a级毛片在线免费| 亚洲高清一区二区三区电影| 国产AV无码专区亚洲A∨毛片| 亚洲黄片手机免费观看| 亚洲性久久久影院| 亚洲中文字幕伊人久久无码| 精品国产亚洲男女在线线电影 | 国产jizzjizz视频全部免费| 午夜免费不卡毛片完整版| 成年女人色毛片免费看| 在线免费观看中文字幕| 卡一卡二卡三在线入口免费| 麻豆成人精品国产免费| 又大又硬又爽免费视频| 亚洲精品无码激情AV| 亚洲午夜福利在线观看| 久久久久无码精品亚洲日韩| 亚洲好看的理论片电影| 亚洲AV成人无码天堂| 亚洲av色香蕉一区二区三区蜜桃| 看一级毛片免费观看视频| 精品免费久久久久国产一区 | 亚洲成av人片在www鸭子| 美女黄网站人色视频免费| g0g0人体全免费高清大胆视频| 在线观看免费黄网站| 久久久久高潮毛片免费全部播放| 免费精品国偷自产在线在线| 日韩电影免费在线| 国产日韩成人亚洲丁香婷婷| 久久99国产亚洲精品观看| 亚洲一区二区三区亚瑟| 国产亚洲精品美女| 永久在线观看免费视频| 免费视频专区一国产盗摄| 国产午夜免费福利红片| 亚洲国产综合精品中文第一区| 亚洲精品第一综合99久久| 特a级免费高清黄色片| 久久久久久久久久国产精品免费| 免费无码精品黄AV电影|