zoukankan      html  css  js  c++  java
  • Java原子操作类AtomicInteger应用场景

    Java中有那么一些类,是以Atomic开头的。这一系列的类我们称之为原子操作类。以最简单的类AtomicInteger为例。它相当于一个int变量,我们执行Int的 i++ 的时候并不是一个原子操作。而使用AtomicInteger的incrementAndGet却能保证原子操作。具体的类如下:

    闲话不多说,还是用实例说话吧。

    问题:现在有2个线程,分别将全局整型变量 i 进行加1。每个线程执行5000次。按照传统的int使用方式,代码如下:

    private static int m = 0;
    
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch cdl = new CountDownLatch(2);
    
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 5000; j++) {
                    m++;
                }
                cdl.countDown();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 5000; j++) {
                    m++;
                }
                cdl.countDown();
            }
        });
        t1.start();
        t2.start();
    
        cdl.await();
        System.out.println("result=" + m);
    }

    最后我们执行上面的代码,结果有可能是10000,但是大多数时候不是10000,而是随机的一些数字。这里的问题就在于 m++,如果我们在 m++的时候加上关键字synchronized也能解决该并发问题。但是synchronized过于沉重。于是我们可以考虑使用原子操作类AtomicInteger来实现。具体实现代码如下:

    public static void main(String[] args) throws InterruptedException {
        CountDownLatch cdl = new CountDownLatch(2);
        AtomicInteger i = new AtomicInteger(0);
    
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 5000; j++) {
                    i.incrementAndGet();
                }
                cdl.countDown();
            }
        });
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int j = 0; j < 5000; j++) {
                    i.incrementAndGet();
                }
                cdl.countDown();
            }
        });
        t1.start();
        t2.start();
    
        cdl.await();
        System.out.println("result=" + i.get());
    }

    现在我们无论执行多少次,结果总是10000。

    说明:

    1. m++并不是一个原子操作,而incrementAndGet却是原子操作方法
  • 相关阅读:
    CodeForces gym Nasta Rabbara lct
    bzoj 4025 二分图 lct
    CodeForces 785E Anton and Permutation
    bzoj 3669 魔法森林
    模板汇总——快读 fread
    bzoj2049 Cave 洞穴勘测 lct
    bzoj 2002 弹飞绵羊 lct裸题
    HDU 6394 Tree 分块 || lct
    HDU 6364 Ringland
    nyoj221_Tree_subsequent_traversal
  • 原文地址:https://www.cnblogs.com/duanjt/p/9717386.html
Copyright © 2011-2022 走看看