AtomicInteger使用方式及源码介绍

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

做者:JavaGieGie面试

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

前言

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

正文

1. 使用场景

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

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 操做。ide

  1. get

获取AtomicInteger当前值。高并发

4. 源码简介

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

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开发零到壹 第一时间阅读,而且能够获取面试资料学习视频等,有兴趣的小伙伴欢迎关注,一块儿学习,一块儿哈🐮🥃。

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