AtomicIntegerArray

AtomicIntegerArray 能解决什么问题?什么时候使用 AtomicIntegerArray?

可以用原子方式更新其元素的 int 数组

如何使用 AtomicIntegerArray?

1)多线程环境下需要对整形数组中的单个值执行原子更新时使用 AtomicIntegerArray。

使用 AtomicIntegerArray 有什么风险?

1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升

AtomicIntegerArray 核心操作的实现原理?

创建实例

    private static final VarHandle AA
= MethodHandles.arrayElementVarHandle(int[].class); /**
* 存储 int 值的数组
*/
private final int[] array; /**
* 创建给定长度的新 AtomicIntegerArray 实例,所有元素的值都为 0。
*/
public AtomicIntegerArray(int length) {
array = new int[length];
}

读取指定索引处的值

    /**
* 读取指定索引处的值
* with memory effects as specified by {@link VarHandle#getVolatile}.
*/
public final int get(int i) {
return (int)AtomicIntegerArray.AA.getVolatile(array, i);
}

以原子方式将索引 i 处的元素值加 1,并返回旧值

    /**
* 以原子方式将索引 i 处的元素值加 1,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndIncrement(int i) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, 1);
}

以原子方式将索引 i 处的元素值减 1,并返回旧值

    /**
* 以原子方式将索引 i 处的元素值减 1,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndDecrement(int i) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, -1);
}

以原子方式将索引 i 处的元素值加 delta,并返回旧值

    /**
* 以原子方式将索引 i 处的元素值加 delta,并返回旧值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int getAndAdd(int i, int delta) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, delta);
}

以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值】计算后的新值,并返回旧值

    /**
* 以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值】计算后的新值,并返回旧值
*/
public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
int prev = get(i), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = updateFunction.applyAsInt(prev);
}
if (weakCompareAndSetVolatile(i, prev, next)) {
return prev;
}
haveNext = prev == (prev = get(i));
}
}

以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值和参考值】计算后的新值,并返回旧值

    /**
* 以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值和参考值】计算后的新值,并返回旧值
*/
public final int getAndAccumulate(int i, int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(i), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = accumulatorFunction.applyAsInt(prev, x);
}
if (weakCompareAndSetVolatile(i, prev, next)) {
return prev;
}
haveNext = prev == (prev = get(i));
}
}

以原子方式将索引 i 处的元素值加 1,并返回新值

    /**
* 以原子方式将索引 i 处的元素值加 1,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int incrementAndGet(int i) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, 1) + 1;
}

以原子方式将索引 i 处的元素值减 1,并返回新值

    /**
* 以原子方式将索引 i 处的元素值减 1,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int decrementAndGet(int i) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, -1) - 1;
}

以原子方式将索引 i 处的元素值加 delta,并返回新值

    /**
* 以原子方式将索引 i 处的元素值加 delta,并返回新值
* with memory effects as specified by {@link VarHandle#getAndAdd}.
*/
public final int addAndGet(int i, int delta) {
return (int)AtomicIntegerArray.AA.getAndAdd(array, i, delta) + delta;
}

以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值】计算后的新值,并返回新值

    /**
* 以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值】计算后的新值,并返回新值。
*/
public final int updateAndGet(int i, IntUnaryOperator updateFunction) {
int prev = get(i), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = updateFunction.applyAsInt(prev);
}
if (weakCompareAndSetVolatile(i, prev, next)) {
return next;
}
haveNext = prev == (prev = get(i));
}
}

以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值和参考值】计算后的新值,并返回新值

    /**
* 以原子方式将索引 i 处的元素值更新为函数式接口【参数为旧值和参考值】计算后的新值,并返回新值
*/
public final int accumulateAndGet(int i, int x,
IntBinaryOperator accumulatorFunction) {
int prev = get(i), next = 0;
for (boolean haveNext = false;;) {
if (!haveNext) {
next = accumulatorFunction.applyAsInt(prev, x);
}
if (weakCompareAndSetVolatile(i, prev, next)) {
return next;
}
haveNext = prev == (prev = get(i));
}
}

AtomicIntegerArray 源码分析的更多相关文章

  1. Java并发包源码分析

    并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多个 ...

  2. Java高并发之无锁与Atomic源码分析

    目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...

  3. ABP源码分析一:整体项目结构及目录

    ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...

  4. HashMap与TreeMap源码分析

    1. 引言     在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...

  5. nginx源码分析之网络初始化

    nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...

  6. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  7. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  8. zookeeper源码分析之三客户端发送请求流程

    znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...

  9. java使用websocket,并且获取HttpSession,源码分析

    转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...

随机推荐

  1. lambda map() filter() zip()练习

    练习: 用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb l=[{'name':'alex'},{'name':'y'}] l=[{'name':'alex'},{'name': ...

  2. [LeetCode] 132. 分割回文串 II

    题目链接 : https://leetcode-cn.com/problems/palindrome-partitioning-ii/ 题目描述: 给定一个字符串 s,将 s 分割成一些子串,使每个子 ...

  3. 剑指offer-树的子结构-python

    题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构)     思路 空树不是任意一个树的子结构,如果 root1 与root2 中有一个为空树的话,返回 ...

  4. 中国各个省市县的人口统计,echart展示

    公司要做一个excel形式的人口统计表,我感觉应该更直观一些展示,所以就选用了echart进行展示,由于时间短所以制作的比较简单粗糙,但相应的数据还是有很大的可参考性. 刚好下载了jfinal3.5, ...

  5. IDEA显示Run Dashboard窗口

    接下来在workspace.xml RunDashBoard节点中添加如下内容:<component name="RunDashboard"> 在代码中加入 <o ...

  6. SQL SERVER将多行数据合并成一行(转)

    1)比如表中有三列数据: 2)执行如下查询: 1 SELECT [USER_NAME], [USER_ACCOUNT] 2 , [ROLE_NAME] = stuff(( 3 SELECT ',' + ...

  7. 用Python编写一个ftb

    程序文件结构 具体代码实现 服务端: 执行文件bin/ftb_server import os,sys PATH = os.path.dirname(os.path.dirname(os.path.a ...

  8. poj3494Largest Submatrix of All 1’s(最大全1子矩阵)

    题目链接:http://poj.org/problem?id=3494 题目大意: 出1个M*N的矩阵M1,里面的元素只有0或1,找出M1的一个子矩阵M2,M2中的元素只有1,并且M2的面积是最大的. ...

  9. Git提交代码的正确姿势

    按此步骤基本没问题,中间有conflict,需要手动解决. 1.git stash 2.git pull 3.git stash pop 4.git add --xxx 5.git commit -m ...

  10. vue2.0发布

    http://blog.csdn.net/xuefeiliuyuxiu/article/details/78970815