最近在网上找到好多的多线程关于原子性的例子,说的都不是非常的明确,对于刚学习多线程的新手而言很容误导学员,在这里,我通过多个例子对多线程的原子性加以说明。
package face.thread.volatilep; public class Counter2 { private int count = 0; public synchronized void inc() { count = count + 1; } public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 final Counter2 c = new Counter2(); for (int i = 0; i < 1000; i++) { new Thread(new Runnable() { @Override public void run() { c.inc(); } }).start(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } //这里每次运行的值都有可能不同,可能为1000 System.out.println("运行结果:Counter.count=" + c.count); } }
以上代码打印的结果偶尔会等于1000,基本上都会有一些误差,原因是线程执行的顺序无法保证的,很可能在新建的1000个线程还没有执行完,我们的代码
System.out.println("运行结果:Counter.count=" + Counter.count);
就已经执行完了,要想解决这个问题很简单,那就是在最后一句println之前在线程睡眠一段时间,比如睡眠2秒钟。等1000个线程执行完了,在打印"
"运行结果:Counter.count=" + Counter.count";
还可以借助于线程辅助类解决,在这里就举例一个最简单的例子展示:
package face.thread.volatilep; import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; public class Counter3 { int count =0; public synchronized void inc() { count++; } public static void main(String[] args) { //同时启动1000个线程,去进行i++计算,看看实际结果 final Counter3 c = new Counter3(); final CyclicBarrier cy = new CyclicBarrier(10000, new Runnable() { public void run() { //这里每次运行的值都有可能不同,可能为1000 System.out.println("运行结果:Counter.count=" + c.count); } }); for (int i = 0; i < 10000; i++) { new Thread(new Runnable() { @Override public void run() { c.inc(); try { cy.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }).start(); } } }
package face.thread.volatilep; import java.util.concurrent.atomic.AtomicInteger; public class CounterNew2{ AtomicInteger count = new AtomicInteger(0); public void increment() { count.getAndIncrement(); } public int getCount() { return count.get(); } public static void main(String[] args) { final CounterNew2 cn = new CounterNew2(); for(int i = 0 ; i < 10000;i++){ new Thread(new Runnable() { public void run() { cn.increment(); } }).start(); } try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("count最终返回值:" + cn.getCount()); } }运行结果也是:10000
原文:http://www.cnblogs.com/chen1-kerr/p/6900051.html