代码:
class MyData{ //int number = 0 ; volatile int number = 0 ; public void setTo60(){ this.number = 60; } //此时number前加volatile修饰,但是不保证原子性 public void addPlusPlus(){ number ++; } AtomicInteger atomicInteger = new AtomicInteger(); public void addMyAtomic(){ atomicInteger.getAndIncrement(); } } /** * 1 验证wolatile可见性 * 2 验证wolatile不保证原子性 * 原子性:完整性,不可分割性。某个线程在做某个业务时,不可以被加塞或被分割,需要整体完成,要么同时成功,要么同时失败。 * volatile不保证原子性原因:i++,实际上分为4步,取值,+,更新主物理内存;volatile不保证更新主物理内存时,线程竞争存在覆盖重写,丢数据。 * 解决方法:1 使用synchronized (大材小用) 2 使用juc下的 AtomicInteger(原子……) * 3 验证wolatile禁止重排 */ public class VolatileDemo { public static void main(String[] args){ //seeOkByVolatile(); final MyData myData = new MyData(); for (int i =1;i<=20;i++) { final Thread aa = new Thread() { @Override public void run() { for (int j = 1; j<= 2000; j ++) { myData.addPlusPlus(); myData.addMyAtomic(); } }; }; aa.start(); }; //两个线程 主线程 和 垃圾回收线程 while (Thread.activeCount()>2){ Thread.yield(); } //number 永远《=40000;atomicInteger=40000 因为更新主内存时覆盖值原因,丢失值。 System.out.println(Thread.currentThread().getName()+" final number is " + myData.number + "; final AtomicInteger is " + myData.atomicInteger); }}