volatile可以保證所有線程看見的值都是最新的,atomic可以保證+-的原子性操作。
每個線程都有自己獨立的數據塊,對於共享變量,它們先將其拷貝到自己的內存空間,創建一個副本,之後再進行的操作針對的都是副本,最後在線程退出前的某一時刻把值再放回到共享變量中。而volatile保證了每次在線程內存空間中副本的變化都會直接映射到共享內存之中,使共享內存中的變量值始終爲最新的。
但volatile對於如下情況便會失效:
T1 load i
T2 load i
T1 store i+1
T2 store i+1
兩個線程對i進行操作,本意是實現i=i+2,但最後只實現了i=i+1。
面對這種情況,可以使用atomic類,它在volatile的基礎之上,實現了+-的原子性操作。即當多線程訪問時,變量的+-與賦值兩步變爲了一步操作。
AtomicInteger atomicInteger = new AtomicInteger(5);
atomicInteger.incrementAndGet();
atomicInteger.getAndIncrement();
atomicInteger.addAndGet(5);
atomicInteger.getAndAdd(5);
atomicInteger.getAndDecrement();
atomicInteger.decrementAndGet();
getAndAdd與addAndGet的區別就是i++與++i的區別。
總結:
atomic比volatile更靠譜,但volatile比atomic開銷小。