天天看點

java并發機制_Java并發機制的底層實作原理.PDF

Java并發機制的底層實作原理

Chapter 2 第2 章

Java 并發機制的底層實作原理

Java 代碼在編譯後會變成 Java 位元組碼,位元組碼被類加載器加載到 JVM 裡,JVM 執行字

節碼,最終需要轉化為彙編指令在 CPU 上執行 ,Java 中所使用的并發機制依賴于 JVM 的實

現和 CPU 的指令。本章我們将深入底層一起探索下 Java 并發機制的底層實作原理。

2.1 volatile 的應用

在多線程并發程式設計中 synchronized 和 volatile 都扮演着重要的角色,volatile 是輕量級的

synchronized ,它在多處理器開發中保證了共享變量的“可見性”。可見性的意思是當一個線

程修改一個共享變量時,另外一個線程能讀到這個修改的值。如果 volatile 變量修飾符使用

恰當的話,它比 synchronized 的使用和執行成本更低,因為它不會引起線程上下文的切換和

排程。本文将深入分析在硬體層面上 Intel 處理器是如何實作 volatile 的,通過深入分析幫助

我們正确地使用 volatile 變量。

我們先從了解 volatile 的定義開始。

1. volatile 的定義與實作原理

Java 語言規範第 3 版中對 volatile 的定義如下 :Java 程式設計語言允許線程通路共享變量,

為了確定共享變量能被準确和一緻地更新,線程應該確定通過排他鎖單獨獲得這個變量。

Java 語言提供了 volatile ,在某些情況下比鎖要更加友善。如果一個字段被聲明成 volatile ,

Java 線程記憶體模型確定所有線程看到這個變量的值是一緻的。

在了解 volatile 實作原理之前 ,我們先來看下與其實作原理相關的 CPU 術語與說明。

第2 章 Java 并發機制的底層實作原理   9

表 2-1 是 CPU 術語的定義。

表2-1 CPU 的術語定義

術  語 英文單詞 術語描述

記憶體屏障 memory barriers 是一組處理器指令,用于實作對記憶體操作的順序限制

緩存中可以配置設定的最小存儲機關。處理器填寫緩存線時會加載整個

緩沖行 cache line

緩存線,需要使用多個主記憶體讀周期

原子操作 atomic operations 不可中斷的一個或一系列操作

當處理器識别到從記憶體中讀取操作數是可緩存的,處理器讀取整個

緩存行填充 cache line f ill

緩存行到适當的緩存(L1 ,L2 ,L3 的或所有)

如果進行高速緩存行填充操作的記憶體位置仍然是下次處理器通路的

緩存命中 cache hit

位址時,處理器從緩存中讀取操作數,而不是從記憶體讀取

當處理器将操作數寫回到一個記憶體緩存的區域時,它首先會檢查這

個緩存的記憶體位址是否在緩存行中,如果存在一個有效的緩存行,則

寫命中 write hit

處理器将這個操作數寫回到緩存,而不是寫回到記憶體,這個操作被稱

為寫命中

寫缺失 write misses the cache 一個有效的緩存行被寫入到不存在的記憶體區域

volatile 是如何來保證可見性的呢?讓我們在 X86 處理器下通過工具擷取 JIT 編譯器生

成的彙編指令來檢視對 volatile 進行寫操作時,CPU 會做什麼事情。

Java 代碼如下。

instance = new Singleton(); //