Java中primite type,如char,integer,bool之類的,它們的讀寫操做都是atomic的,可是有幾個例外:java
這些狀況下,須要使用AutomicInteger,AutomicLong。安全
同時,java中的reference的讀寫也是automic的,雖然reference到底佔幾個字節沒有明肯定義,但至少如下能夠保證:app
因此不管如何,對reference的操做確定是單步操做,是automic的。jvm
事實上,一個蠻有用的例子是cache switch - 你有兩個cache pool,分別用兩個reference指向:cache_in_build和cache_in_use,等cache_in_build完成了,你須要把cache_in_use指向它,沒有問題,這是線程安全的。優化
可是問題是,jvm能夠會reorder你的statement:ui
指望是cache在build完了以後,切換過去。atom
可是這兩行代碼並無先後的dependency關係,因此JVM能夠爲了優化,進行亂序執行,變成:線程
因而,若是另外一個線程在使用cache_in_use,在代碼#1執行完以後,就訪問到了正在build的那個cache,這是個問題。it
解決方案是cache_in_use必須定義爲volatile,保證happen-before的關係,拒絕亂序執行,從而保證其餘線程看到的數據是有效的。im