• 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

  • 相关阅读:
    [SDOI2012]任务安排
    JavaScript数据存储和深浅拷贝实际运用
    在VUE中使用Echarts
    JavaScript的原型链
    关于JavaScript的43道题①
    JS为什么是单线程的?
    HTTP协议②缓存
    HTTP协议①介绍
    树形结构的数据渲染(element-ui&VUE)
    js中定义变量之②var let const的区别
  • 原文地址:https://www.cnblogs.com/kelelipeng/p/16205804.html
Copyright © 2020-2023  润新知