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. 列表and元组操作

    一.列表  列表是我们以后比较常用的数据类型之一,通过列表我们可以实现对数据的存储.修改等操作. 首先,我们看一下列表的定义: 有了列表以后,我们可以通过下标来访问列表中的元素.注意:下表是从0开始的 ...

  2. unsolved question's solution

    因为很懒,没有时间,只会口胡等等原因,所以有些题目就不打code了 $luogu:$ P1973 [NOI2011]Noi嘉年华: 时间离散化,预处理一个区间$[l,r]$内的最多活动个数$in[l] ...

  3. 去掉img与img之间,video与video之间默认的间距(3种方式)

    img,video{ /*第1种方式*/ border:; vertical-align: bottom; /*第2种方式*/ outline-width:0px; vertical-align:to ...

  4. 在Python中使用protobuf2.6.1 string format utf-8 and unicode error

    版本信息: protobuf: v2.6.1 python: 2.7 关于在Python中使用protobuf时 string格式字段的编码问题 在python中编码格式多采用utf-8格式.而pro ...

  5. class path resource [applicationContext.xml] cannot be opened because it does not exis

    使用maven创建web工程,将spring配置文件applicationContext.xml放在src/resource下,用eclipse编译时提示class path resource [ap ...

  6. Codeforces Round #426 (Div. 2) - D

    题目链接:http://codeforces.com/contest/834/problem/D 题意:给定一个长度为n的序列和一个k,现在让你把这个序列分成刚好k段,并且k段的贡献之和最大.对于每一 ...

  7. 牛客练习赛49 B 筱玛爱阅读 (状压DP,子集生成)

    链接:https://ac.nowcoder.com/acm/contest/946/B 来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262875K,其他语言5257 ...

  8. C#基础知识之DirectorySearcher 类

    活动目录(Active Directory)是从一个数据存储开始的,它采用了类似Exchange Server的数据存储,所以被称为Extensible Storage Service (ESS).其 ...

  9. IP地址转二进制

    例如216这个数 216 = 1 * 128 +1 * 64 + 0 * 32 + 1 * 16 + 1 * 8 + 0 * 4 + 0 * 2 + 0 * 1 提取乘号之前的数字我们得到所代表的二进 ...

  10. 安装了sql-alchemy但导入sql_alchemy时失败

    问题描述:按成flask-sqlalchemy成功了,但是项目导入flask_alchemy时出错 但是,发现在代码中还是导入不了 之后发现问题,到file->setting->proje ...