中国品牌网站,wordpress网站名称函数,郑州市建设网官网,企业管理系统有最近在网上找到好多的多线程关于原子性的例子#xff0c;说的都不是非常的明确#xff0c;对于刚学习多线程的新手而言很容误导学员#xff0c;在这里#xff0c;我通过多个例子对多线程的原子性加以说明。 例子一#xff1a;传统技术自增 package face.thread.volatilep;…最近在网上找到好多的多线程关于原子性的例子说的都不是非常的明确对于刚学习多线程的新手而言很容误导学员在这里我通过多个例子对多线程的原子性加以说明。 例子一传统技术自增 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() {Overridepublic void run() {c.inc();}}).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//这里每次运行的值都有可能不同,可能为1000System.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() {//这里每次运行的值都有可能不同,可能为1000System.out.println(运行结果:Counter.count c.count);}});for (int i 0; i 10000; i) {new Thread(new Runnable() {Overridepublic void run() {c.inc();try {cy.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}}}).start();}}
} 例子二原子性自增 原子是世界上的最小单位具有不可分割性。比如 a0a非long和double类型 这个操作是不可分割的那么我们说这个操作时原子操作。再比如a 这个操作实际是a a 1是可分割的所以他不是一个原子操作。非原子操作都会存在线程安全问题需要我们使用同步技术sychronized来让它变成一个原子操作。一个操作是原子操作那么我们称它具有原子性。Java的concurrent包下提供了一些原子类我们可以通过阅读API来了解这些原子类的用法。比如AtomicInteger、AtomicLong、AtomicReference等。 因为原子性是线程安全的所以关于原子性自增是不需要传统的加锁技术的具体看代码 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 转载于:https://www.cnblogs.com/chen1-kerr/p/6900051.html