CPU內存模型 和 JAVA內存模型 講解

CPU 內存模型

在講解 JAVA 內存模型以前,先了解 CPU 內存模型,由於JAVA內存模型跟它是十分類似的。 java

CPU內存模型
圖中的 Core 就是一個 CPU。能夠看得出:

  1. L1 和 L2 是每一個CPU本身的高速緩存
  2. L3 是多個CPU之間共享緩存。
  3. 黃色的就是主內存。
  4. L一、L二、L3 的存儲的速度、以及存儲的東西逐漸減小。
  5. L1 和 L2 的緩存命中率均爲 80%
  6. 達到 L3 緩存的數據佔比 4% 左右。

JAVA 內存模型

在這裏插入圖片描述
能夠看得出這個跟 CPU 內存時十分類似的。黃色部分 Memory 至關於 CPU 的 L3 緩存了。 同時也能夠看到啊, Copy Memory 是拷貝過來的。也正由於這個東西的存在,引出了變量的可見性問題。

可見性問題

class XXX {
	private static int a = 0;
	Thread threadA = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " a = " + a);
            a = 1;
            System.out.println(Thread.currentThread().getName() + " a = " + a);
        }, "ThreadA");


        Thread threadB = new Thread(() -> {
            System.out.println(Thread.currentThread().getName() + " a = " + a);
            a = 1;
            System.out.println(Thread.currentThread().getName() + " a = " + a);
        }, "ThreadB");
}
複製代碼

當 new 多個線程去修改 a 這個變量時,就會出現可見性問題。也就是 : thread-A :a ->1 。可是 thread-B 不必定讀到 a 就是1,可能仍是 0 ;緩存

重排序問題

簡單解釋:

java 在執行程序時,可能會對指令進行重排。也就是按照代碼順序:app

b = 1;
x = a;
複製代碼

可是執行時可能會變成:spa

x = a;
b = 1;
複製代碼

源代碼到真正執行通常會通過: 源代碼 -> 編譯器重排序 -> 處理器重排序 -> 最終執行順序線程

可是呢!!! 重排序也不是無條件去重排序的。他必須遵循一個 happen-before 規則。3d

happen-before 規則:

在這裏插入圖片描述
相關文章
相關標籤/搜索