一、问题描述
在多线程并发的环境下,java关键字volatile累加不能保证数据同步,会出现线程的读/写操作重叠现象(点击查看图文说明具体产生原因),如下图代码示例说明。
package com.xwood.demo.thread;@b@@b@public class TestVolatile_1 {@b@@b@ public static volatile int num = 0;@b@ public static void main(String[] args) throws Exception {@b@ for (int i = 0; i <100; i++) {@b@ new Thread(new Runnable() {@b@ @Override@b@ public void run() {@b@ for (int i = 0; i <20000; i++) {@b@ num++;//num++不是一个原子性操作@b@ }@b@ }@b@ }).start();@b@ }@b@ Thread.sleep(3000);//休眠3秒,确保创建的100个线程都已执行完毕@b@ System.out.println(num);@b@ }@b@@b@}
控制台打印结果(逾期结果100*20000=2000000)
1900012
二、解决方法
通过AtomicInteger关键字解决不一致问题,具体代码效果如下(更多代码示例&教程请点击下载)
package com.xwood.demo.thread;@b@@b@import java.util.concurrent.atomic.AtomicInteger;@b@@b@public class TestVolatile_2 {@b@ public static AtomicInteger num = new AtomicInteger(0);@b@ public static void main(String[] args) throws Exception {@b@ for (int i = 0; i <100; i++) {@b@ new Thread(new Runnable() {@b@ @Override@b@ public void run() {@b@ for (int i = 0; i <20000; i++) {@b@ num.incrementAndGet() ;// num自增,功能上相当于int类型的num++操作@b@ }@b@ }@b@ }).start();@b@ }@b@ Thread.sleep(3000);//休眠3秒,确保创建的100个线程都已执行完毕@b@ System.out.println(num);@b@ }@b@}
控制台运行结果
2000000