AtomicIntegerArray 的常用方法

1. AtomicIntegerArray 是什么?

AtomicIntegerArray 就是:

线程安全的 int[] 数组。

普通数组:

java 复制代码
int[] array = new int[10];

而原子数组:

java 复制代码
AtomicIntegerArray array = new AtomicIntegerArray(10);

区别在于:

复制代码
int[]
 ↓
普通数组
 ↓
多个线程同时修改同一个元素时,不保证原子性


AtomicIntegerArray
 ↓
原子数组
 ↓
对元素的修改可以进行原子操作

2. 最基本的创建方式

方式一:指定长度

java 复制代码
AtomicIntegerArray array = new AtomicIntegerArray(5);

相当于:

复制代码
下标:  0   1   2   3   4
       ↓   ↓   ↓   ↓   ↓
      [0] [0] [0] [0] [0]

方式二:根据已有数组创建

java 复制代码
int[] source = {10, 20, 30};

AtomicIntegerArray array =
        new AtomicIntegerArray(source);

此时:

复制代码
index   0    1    2
        ↓    ↓    ↓
       10   20   30

3. 获取元素:get()

java 复制代码
int value = array.get(0);

意思:

获取下标 0 的元素。

例如:

java 复制代码
AtomicIntegerArray array =
        new AtomicIntegerArray(new int[]{10, 20, 30});

System.out.println(array.get(1));

输出:

复制代码
20

4. 修改元素:set()

java 复制代码
array.set(0, 100);

意思:

把下标 0 的元素修改成 100。

例如:

复制代码
原来:

[10, 20, 30]

array.set(0, 100)

变成:

[100, 20, 30]

5. 最重要的:incrementAndGet()

这个你刚才那个 Incrementer 示例里面就用到了。

java 复制代码
array.incrementAndGet(0);

意思:

把下标 0 的元素原子地 +1,然后返回新值。

例如:

java 复制代码
AtomicIntegerArray array =
        new AtomicIntegerArray(new int[]{10, 20, 30});

int result = array.incrementAndGet(0);

执行:

复制代码
10 → 11

所以:

复制代码
result == 11

6. getAndIncrement()

这个和刚才一样,也特别容易搞混。

java 复制代码
int result = array.getAndIncrement(0);

意思:

先返回旧值,再 +1。

例如:

复制代码
原来:
10

getAndIncrement()

返回:
10

数组变成:
11

所以:

复制代码
incrementAndGet()
    ↓
先 +1,再返回


getAndIncrement()
    ↓
先返回,再 +1

7. decrementAndGet()

同样:

java 复制代码
array.decrementAndGet(0);

就是:

下标 0 的元素原子地 -1,并返回新值。

例如:

复制代码
10 → 9

8. getAndDecrement()

java 复制代码
int result = array.getAndDecrement(0);

就是:

复制代码
原来:10

返回:10

然后:
10 → 9

所以和 increment 是完全一样的规律。


9. addAndGet()

这个也很常用。

复制代码
array.addAndGet(0, 10);

意思:

把下标 0 的元素原子地加 10,并返回新值。

例如:

复制代码
原来:

[100, 20, 30]

addAndGet(0, 10)

↓

[110, 20, 30]

返回:

复制代码
110

10. getAndAdd()

java 复制代码
int result = array.getAndAdd(0, 10);

意思:

先返回旧值,再加 10。

例如:

复制代码
原来:100

返回:100

然后:
100 → 110

11. 为什么它比 int[] 安全?

这是你学习 AtomicIntegerArray 最重要的地方。

假设:

java 复制代码
int[] array = {0};

两个线程同时:

java 复制代码
array[0]++;

本质上还是:

复制代码
读取
 ↓
+1
 ↓
写回

所以可能出现:

复制代码
线程A读取 0
线程B读取 0

线程A写入 1
线程B写入 1

最终 = 1

而:

java 复制代码
AtomicIntegerArray array =
        new AtomicIntegerArray(1);

两个线程执行:

java 复制代码
array.incrementAndGet(0);

底层会使用类似 CAS 的原子更新机制。

因此:

复制代码
线程A:0 → 1
线程B:发现0已经变成1
       ↓
       重新尝试
       ↓
       1 → 2

最终:

复制代码
2

12. 你现在把它和 AtomicInteger 放一起理解

这个非常重要:

复制代码
AtomicInteger
    ↓
原子地操作一个 int


AtomicIntegerArray
    ↓
原子地操作 int[] 中的某个元素

例如:

java 复制代码
AtomicInteger count = new AtomicInteger(0);

count.incrementAndGet();

相当于:

java 复制代码
AtomicIntegerArray array =
        new AtomicIntegerArray(10);

array.incrementAndGet(3);

前者操作的是:

复制代码
一个 int

后者操作的是:

复制代码
数组下标 3 的 int

你把 AtomicIntegerArray 理解成"AtomicInteger 的数组版",基本就对了。

相关推荐
LayZhangStrive22 天前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
程序员二叉2 个月前
【JUC】ThreadLocal底层原理|内存泄漏|弱引用|跨线程传递方案
java·开发语言·面试·职场和发展·juc
程序员二叉2 个月前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
程序员二叉2 个月前
【JUC】AQS底层深度拆解|独占/共享模式|队列原理全详解
java·开发语言·面试·juc
fengxin_rou2 个月前
Java并发手撕题详解:原理、实现与面试避坑指南
多线程·cas·juc·lru
fengxin_rou2 个月前
【从零开始的JUC并发第四章】:JUC常用工具类
并发·juc
better_liang3 个月前
每日Java面试场景题知识点之-JUC并发编程核心原理与实战
java·线程池·并发编程·juc·aqs·reentrantlock·concurrenthashmap
fengxin_rou3 个月前
【juc第三章】:AQS机制全解
juc