600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > 多线程并发之原子性(六)

多线程并发之原子性(六)

时间:2020-12-11 08:38:46

相关推荐

多线程并发之原子性(六)

最近在网上找到好多的多线程关于原子性的例子,说的都不是非常的明确,对于刚学习多线程的新手而言很容误导学员,在这里,我通过多个例子对多线程的原子性加以说明。

例子一:传统技术自增

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();}}}

例子二:原子性自增

原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。