CAS AtomicInteger的基本用法

AtomicInteger的基本用法

1、AtomicInteger的常用方法

i++和++i不是线程安全的,因此在高并发的情况下,需要使用synchronized等关键字来保证线程安全,但是AtomicInteger这个类则是线程安全的

public static void main(String[] args) {

        AtomicInteger int1=new AtomicInteger();
        System.out.println("AtomicInteger的默认值为:"+int1);

        //对数据赋值
        int1.set(123);
        //获取数据值
        System.out.println("获取数据的值为:  "+int1.get());

        //先相加,再获取值
        System.out.println("先与12相加,再获取值:  "+int1.addAndGet(12));
        //先获取值,再相加
        System.out.println("先获取值,再与12相加:  "+int1.getAndAdd(12));
        //先获取值,再赋新值
        System.out.println("先获取值,再赋新值100:  "+int1.getAndSet(100));
        //自减1,再获取值
        System.out.println("自减1,再获取值:  "+int1.decrementAndGet());
        //自增1,再获取值
        System.out.println("自增1,再获取值:  "+int1.incrementAndGet());
        //先获取值,再自减1
        System.out.println("先获取值,再自减1:  "+int1.getAndDecrement());
        //先获取值,再自增1
        System.out.println("先获取值,再自增1:  "+int1.getAndIncrement());

    }

 

运行结果:

AtomicInteger的默认值为:0
获取数据的值为:  123
先与12相加,再获取值:  135
先获取值,再与12相加:  135
先获取值,再赋新值100:  147
自减1,再获取值:  99
自增1,再获取值:  100
先获取值,再自减1:  100
先获取值,再自增1:  99

 

2、boolean compareAndSet(int expect, int update)

示例1:

    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(100);
        System.out.println("变量的初始值:"+atomicInteger.get());

        int expectedValue = 123;
        int newValue      = 234;
        Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
        System.out.println("执行compareAndSet后返回的bool值:"+b);
        System.out.println("执行compareAndSet后变量的值:"+atomicInteger);

    }

 

运行结果:

变量的初始值:100
执行compareAndSet后返回的bool值:false
执行compareAndSet后变量的值:100

 

示例2:

    public static void main(String[] args) {
        AtomicInteger atomicInteger = new AtomicInteger(123);
        System.out.println("变量的初始值:"+atomicInteger.get());

        int expectedValue = 123;
        int newValue      = 234;
        Boolean b =atomicInteger.compareAndSet(expectedValue, newValue);
        System.out.println("执行compareAndSet后返回的bool值:"+b);
        System.out.println("执行compareAndSet后变量的值:"+atomicInteger);

    }

 

运行结果:

变量的初始值:123
执行compareAndSet后返回的bool值:true
执行compareAndSet后变量的值:234

 

由示例1和示例2比较可以得到如下结论:
atomicInteger变量调用compareAndSet(int expect, int update) 方法时,

  • 如果atomicInteger变量的值与expect相等,则返回true,并且将update赋值给atomicInteger变量

  • 如果atomicInteger变量的值与expect不相等,则返回false,并且atomicInteger变量保持原值不变

3、使用AtomicInteger和int在高并发下的线程安全

public class Counter {
    public static AtomicInteger count=new AtomicInteger();
    public volatile static int countInt=0;
    public static void increase(){
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        countInt++;
        count.getAndIncrement();  //自增
    }

    public static void main(String[] args) throws InterruptedException {
        final CountDownLatch latch=new CountDownLatch(100);

        for(int i=0;i<100;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    Counter.increase();
                    latch.countDown();
                }
            }).start();
        }

        latch.await();

        System.out.println("运行结果:count: "+Counter.count+",countInt: "+countInt);
    }
}

 

运行结果:

运行结果:count: 100,countInt: 99

 

使用AtomicInteger,即使不用同步锁synchronized,最后的结果也是100,可用看出AtomicInteger的作用,用原子方式更新的int值。主要用于在高并发环境下的高效程序处理。使用非阻塞算法来实现并发控制。

总结:

使用AtomicInteger是线程安全的,即使不使用synchronized关键字也能保证其是线程安全的。而且由于AtomicInteger由硬件提供原子操作指令实现,在非激烈竞争的情况下,开销更小,速度更快

转自:https://www.jianshu.com/p/bc7b6f14984e

 

 

posted @ 2022-04-29 10:48  kelelipeng  阅读(79)  评论(0编辑  收藏  举报