动态

详情 返回 返回

volatile - 动态 详情

volatile特性
保證可見性,不保證原子性,
讀寫禁止指令重排序
volatile寫操作之前 StoreStore,寫之後StoreLoad
volatile讀操作之後 LoadLoad LoadStore

image.png

為什麼會不一致
1、線程本地內存共享變量的副本讀,沒有立即同步到主內存,出現了可見性問題。主內存是所有線程共享的,每個線程都有工作內存,不共享線程工作時,把共享變量拷貝到工作內存中,在工作內存中讀寫寫完之後,可能沒有立即更新到主存中去,導致其他線程拷貝不到最新數據更新到主存之後,可能也沒有立即同步到其他線程中。
2、CPU多級緩存架構,寫完L1的數據,不會立即同步到主內存,及時同步到主內存,也可能不會立即加載到其他CPU的L1緩存中,其他的L1緩存使用的還是舊的數據

volatile為什麼能保證可見性
數據小於緩存行大小,小於64bytes,MESI緩存一致性協議
數據大於緩存行數據,用總線鎖保證數據一致

MESI協議
CPU的緩存行大小為64bytes,每個緩存行使用額外的兩位來標記狀態
Modified:當數據處於Modified狀態時,該CPU會監聽緩存行對應主存的數據,一旦監聽到,會將緩存行數據寫會主存,並標記為Shared
Exclusive:會監聽緩存行對應主存的數據讀取,一旦監聽到,緩存行數據標記為Shared狀態。
Shared:會監聽緩存行對應主存數據的寫入,一旦監聽到,緩存行數據變為Invalid狀態。
Invalid:讀取數據從主存中加載,否則從讀取高速緩存。

為什麼dcl單例需要volatile

1、NEW designpattern/singleton/TestSingle06
    DUP
2、INVOKESPECIAL designpattern/singleton/TestSingle06.<init> ()V
3、ARETURN

創建對象步驟:
1、對象分配內存地址
2、成員變量賦值
3、引用指向步驟1分配的內存地址

1、2指令不能重排序,23指令可以重排序
如果23重排序了,那麼其他線程可能拿到了沒有賦成員變量值的對象

Add a new 评论

Some HTML is okay.