violate保證了可見性可是不能保證原子性的狀況;安全
解決了vialate關鍵字不能保證原子性(線程安全)併發
要求,一個線程去將count+1000的操做,輸出1000,2000~~~~10000ide
使用vialate打印出來的很明顯不符合要求,vialate只能保證可見性,不能保證原子性。atom
violate保證了可見性緣由:當關鍵字使用了violate事後,線程數據一更新就會寫到主內存中去,並讓其餘線程的引用失效。好比A線程和B線程都引用了violate修飾的變量,當A線程更改事後,會讓B線程中的變量失效,當B要用變量時只能從主內存中去取,因此保證了可見性(不能保證原子性的緣由:下面)線程
violate保證了可見性可是不能保證原子性的緣由:假如A線程讀取到的數是0,在執行1000次++操做中(++不是原子性操做,會執行三次,取值、+一、賦值),其中一次出現阻塞的狀況,並不會去讓其餘線程的值失效,因此其餘的線程有可能拿到的不是最後的執行結果1000。code
使用Atomic併發包就能保證,注意必需要加static修飾,由於加了static,表示這個就是單例,只有一個,若是不加static的話,每一次都是新的,都是1000內存
class VolatileNoAtomic extends Thread { // private static volatile int count = 0; private static AtomicInteger atomicInteger=new AtomicInteger(0); @Override public void run() { for (int i = 0; i < 1000; i++) { // count++; atomicInteger.incrementAndGet(); //count++; } System.out.println(getName() + "-----" + atomicInteger); } } public class VolatileNoAtomicDemo { public static void main(String[] args) { // 初始化10個線程 VolatileNoAtomic[] volatileNoAtomic= new VolatileNoAtomic[10]; for (int i = 0; i < volatileNoAtomic.length; i++) { //建立每個線程 volatileNoAtomic[i]=new VolatileNoAtomic(); } for (int i = 0; i < volatileNoAtomic.length; i++) { //啓動每個線程 volatileNoAtomic[i].start(); } } }
依次輸出1000,2000~~~10000,可是線程的順序不必定同樣,由於線程的優先級由CPU來選擇rem