AtomicInteger使用方式及源码介绍

作者:JavaGieGie

微信公众号:Java开发零到壹

这是我参与更文挑战的第 9 天,活动详情查看:更文挑战

前言

AtomicInteger是java.util.concurrent.atomic 包下的一个原子类,该包下还有AtomicBoolean, AtomicLong,AtomicLongArray, AtomicReference等原子类,主要用于在高并发环境下,保证线程安全。

正文

1. 使用场景

我们都知道,a++ 这个操作在多线程并发执行的情况下,是非线程安全的。并且由于a++过程包含三个步骤,即非原子性,所以即使使用volatile也不能保证线程安全;而加锁(如Synchronized)又十分影响性能,因此这个时候非常适用使用AtomicInteger来实现变量的自增。

2. 案例代码

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicIntegerDemo implements Runnable {
    private static final AtomicInteger atomicInteger = new AtomicInteger();

    //增加指定数量
    public void getAndAdd() {
        atomicInteger.getAndAdd(-90);
    }
    //增加1
    public void getAndIncrement() {
        atomicInteger.getAndIncrement();
    }
    //减少1
    public void getAndDecrement() {
        atomicInteger.getAndDecrement();
    }
    public static void main(String[] args) throws InterruptedException {
        AtomicIntegerDemo r = new AtomicIntegerDemo();
        Thread t1 = new Thread(r);
        t1.start();
        t1.join();
        System.out.println("AtomicInteger操作结果:" + atomicInteger.get());
    }

    @Override
    public void run() {
        for (int i = 0; i < 10000; i++) {
            getAndDecrement();
        }
    }
}
复制代码

3. 方法介绍

  1. getAndIncrement

对变量atomicInteger进行 +1 操作。

  1. getAndAdd

可以对变量atomicInteger进行增加 N(指定增加数量)操作。

  1. getAndDecrement

对变量atomicInteger进行 -1 操作。

  1. get

获取AtomicInteger当前值。

4. 源码简介

这里介绍一下AtomicInteger.incrementAndGet()方法,该方法内有一个死循环,它首先会获取当前值,然后调用compareAndSet方法,判断当前值是否已经被其他线程修改,如果compareAndSet返回false会继续重试,直到成功为止,这也就是AtomicInteger能够实现原子性的精髓。

public final int incrementAndGet() {
    for (;;) {
        int current = get();
        int next = current + 1;
        if (compareAndSet(current, next))
            return next;
    }
}
复制代码

上面提到compareAndSet,这里看下源码:

public final boolean compareAndSet(int expect, int update) {
    return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
复制代码

从源码中可以看到:compareAndSet()调用了Unsafe.compareAndSwapInt()方法,也就是Unsafe类的CAS操作。

CAS会在《蹲坑也能进大厂》系列进行讲解,有兴趣的小伙伴可以关注。

总结

AtomicInteger应用场景也比较单纯,除去高度竞争的情况,原子类相比于普通的锁,粒度更细并且效率也更高,本文对常用方法进行介绍,有需要对源码深入了解的,可以继续探索,有任何疑问可以在文章下方评论哦。

点关注,防走丢

以上就是本期全部内容,如有纰漏之处,请留言指教,非常感谢。我是花GieGie ,有问题大家随时留言讨论 ,我们下期见?。

文章持续更新,可以微信搜一搜 Java开发零到壹 第一时间阅读,并且可以获取面试资料学习视频等,有兴趣的小伙伴欢迎关注,一起学习,一起哈??。

原创不易,你怎忍心白嫖,如果你觉得这篇文章对你有点用的话,感谢老铁为本文点个赞、评论或转发一下,因为这将是我输出更多优质文章的动力,感谢!

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享