volatitle声明的变量不具备原子性.即,当执行++ --这样的操作时,由于不是原子操作,所以还存在线程安全问题.
i = 10; i = i++; i=? ==>10 //解释: tmp=i i=i++ i=tmp
class atoT implements Runnable{ private volatile int s = 0; @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getS()); } private int getS(){ return s++; } } public class atomicTest { public static void main(String[] args) { atoT at = new atoT(); for(int i=0;i<10;i++) new Thread(at).start(); } }
我们可以利用 java.util.concurrent.atomic下的原子变量
原子变量使用了
1 volatile保证了内存的可见性
2 使用CAS (compare-and-swap)算法保证了数据的原子性
V主存值
A 预估值
B 更新值
当且仅当 V==A时,V更新为B
class atoT implements Runnable{ private AtomicInteger s = new AtomicInteger(0); @Override public void run() { try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(getS()); } private int getS(){ return s.getAndIncrement(); } } public class atomicTest { public static void main(String[] args) { atoT at = new atoT(); for(int i=0;i<10;i++) new Thread(at).start(); } }