java併發編程(9)內存模型

JAVA內存模型

  在多線程這一系列中,不去探究內存模型的底層緩存

1、什麼是內存模型,爲何須要它

  在現代多核處理器中,每一個處理器都有本身的緩存,按期的與主內存進行協調;安全

  想要確保每一個處理器在任意時刻知道其餘處理器正在進行的工做,將須要很大的開銷;且一般是不必的多線程

  咱們只有在須要跨線程共享數據時,才須要知道信息;而在JAVA中就是經過正確的同步來實現app

  1.重排序

    以下:判斷輸出的值將十分困難spa

public class PossibleReordering {
    static int x = 0, y = 0;
    static int a = 0, b = 0;

    /**
     * 判斷輸出值將會很是困難:
     * 1:多線程之間的切換,致使可能的輸出值:(0,1)(1,0)(1,1)
     * 2.指令重排序:one線程如a=1和x=b之間重排序,x=b(0),而後other線程被調度執行y=a(0),將致使(0,0)
     */
    public static void main(String[] args) throws InterruptedException {
        Thread one = new Thread(new Runnable() {
            public void run() {
                a = 1;
                x = b;
            }
        });
        Thread other = new Thread(new Runnable() {
            public void run() {
                b = 1;
                y = a;
            }
        });
        one.start();
        other.start();
        one.join();
        other.join();
        System.out.println("( " + x + "," + y + ")");
    }
}

 

   2.JAVA內存模型簡介

    偏序關係:反對稱、自反和傳遞屬性;可是對於任意的兩個元素A和B,並不必定知足A偏向B或B偏向A的關係線程

      如:A和B之間我更偏向B,可是我不必明確的作出選擇code

    JMM爲程序中全部的操做定義了一個偏序關係,稱之爲Happens-Before;要想保證執行B操做的線程看到執行A操做的線程的結果,不管AB是否在同一線程,必須知足Happens-Before關係,不然JVM就會對其重排序對象

    

 

如:加鎖操做,就能夠預知執行順序,多個線程之間就符合Happens-Before,不加鎖則沒法判斷線程之間的調度,blog

  3.發佈

     真正緣由:發佈一個共享對象  和  在另外一個線程中訪問該對象之間沒有Happens-Before關係;因爲指令重排序,致使對象沒有正確構建則被髮布排序

public class UnsafeLazyInitialization {
    private static Resource resource;

    /**
     * 除了竟態條件問題檢查後執行,還有不安全發佈的問題
     * 如:一個線程A進來,看到resource爲null,則實例化並返回;另外一個線程B進來看到resource不爲null直接返回
     * 若是在線程A中對resource進行了修改,則可能在線程B中看不到resource的正確狀態
     */
    public static Resource getInstance() {
        if (resource == null)
            resource = new Resource(); // unsafe publication
        return resource;
    }

    static class Resource {
    }
}
相關文章
相關標籤/搜索