Java中volatile副作用:不使用CPU快取
快取記憶體位於在CPU和主記憶體之間,是一個速度更快的記憶體模組,其總體目的是提升效能。
快取通常是由具有不同大小和訪問時間的幾個層次級別組成。L1快取是最小和最快的。L2更大而更慢。L3更大甚至更慢-但仍然比主記憶體快得多。用於特定資料結構的資料量越少,將其放入快取記憶體的機會就越大,從而可以顯著提高效能。
volatile關鍵字之所以特殊,是因為volatile關鍵字不快取變數的值,並且始終從主記憶體中讀取變數。這意味著它不使用CPU快取,因為它是為了執行緒安全。
原文點選標題,測試案例:
@State(Scope.Thread) public class JMHArrayBenchmarking { private static final int ARRAY_SIZE = 64 * 1024 * 1024; public Integer[] array; public volatile Integer[] vArray; @Setup public void setup() { array = new Integer[ARRAY_SIZE]; vArray = new Integer[ARRAY_SIZE]; Arrays.fill(array, 1); Arrays.fill(vArray, 1); } @TearDown public void cleanup() { array = new Integer[ARRAY_SIZE]; vArray = new Integer[ARRAY_SIZE]; } @Benchmark @BenchmarkMode(Mode.SingleShotTime) public void doMultiply() { for (int i = 0; i < array.length; i++) { array[i] = array[i] * 3; } } @Benchmark @BenchmarkMode(Mode.SingleShotTime) public void doVolatileMultiply() { for (int i = 0; i < vArray.length; i++) { vArray[i] = vArray[i] * 3; } } } |
在上面的示例中,說明了doMultiply()將元素插入到普通陣列中的方法以及doVolatileMultiply()將元素插入到volatile陣列中的方法。透過比較兩種方法的速度,我們可以看到該doVolatileMultiply()方法的執行速度比該doMultiply()方法慢,因為volatile關鍵字不使用CPU快取來儲存元素。它直接從主記憶體中獲取元素,這是為了執行緒安全。
結果:
Benchmark Mode Score Units JMHArrayBenchmarking.doMultiply ss 0.529 s/op JMHArrayBenchmarking.doVolatileMultiply ss 0.570 s/op |
相關文章
- CPU快取一致性協議MESI,memory barrier和java volatile快取協議Java
- 【Java併發程式設計】從CPU快取模型到JMM來理解volatile關鍵字Java程式設計快取模型
- CPU快取快取
- JAVA 拾遺 — CPU Cache 與快取行Java快取
- 從CPU快取看快取的套路快取
- C和C++中的volatile、記憶體屏障和CPU快取一致性協議MESIC++記憶體快取協議
- CPU快取記憶體快取記憶體
- CPU快取是什麼?一二三級快取哪個對CPU最重要?快取
- 多核cpu、cpu快取記憶體、快取一致性協議、快取行、記憶體快取記憶體協議
- CPU快取學習及C6678快取使用總結(知識歸納)快取
- 個人總結-CPU快取快取
- 使用singleflight防止快取擊穿(Java)快取Java
- 在Java中使用redisTemplate操作快取JavaRedis快取
- JAVA快取-Redis入門級使用Java快取Redis
- CPU快取和記憶體屏障快取記憶體
- 談談CPU快取記憶體快取記憶體
- CPU快取重新整理的誤解快取
- Java快取EhcacheJava快取
- java的Integer中也會有快取Java快取
- SpringBoot中Shiro快取使用Redis、EhcacheSpring Boot快取Redis
- C#中普通快取的使用C#快取
- 程式設計中快取的使用程式設計快取
- 解讀CPU快取,它們如何工作的?快取
- Java高併發快取架構,快取雪崩、快取穿透之謎Java快取架構穿透
- Java快取淺析Java快取
- 使用.Net中MediatR快取管道行為快取
- jetcache快取使用快取
- SpringBoot使用快取Spring Boot快取
- 使用Redis和Java進行資料庫快取RedisJava資料庫快取
- 用Java寫一個分散式快取——快取管理Java分散式快取
- 兩分鐘瞭解Java中volatile!Java
- linux 頁框管理(三) 每cpu頁幀快取Linux快取
- CPU快取一致性整理筆記快取筆記
- Java快取備忘大全Java快取
- Java Integer的快取策略Java快取
- nginx快取使用詳解,nginx快取使用及配置步驟Nginx快取
- Java記憶體快取-通過Google Guava建立快取Java記憶體快取GoGuava
- 如何使用 Redis 快取Redis快取