AtomicIntegerArray 源码分析
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 源码分析的更多相关文章
- Java并发包源码分析
并发是一种能并行运行多个程序或并行运行一个程序中多个部分的能力.如果程序中一个耗时的任务能以异步或并行的方式运行,那么整个程序的吞吐量和可交互性将大大改善.现代的PC都有多个CPU或一个CPU中有多个 ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
- HashMap与TreeMap源码分析
1. 引言 在红黑树--算法导论(15)中学习了红黑树的原理.本来打算自己来试着实现一下,然而在看了JDK(1.8.0)TreeMap的源码后恍然发现原来它就是利用红黑树实现的(很惭愧学了Ja ...
- nginx源码分析之网络初始化
nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网 ...
- zookeeper源码分析之五服务端(集群leader)处理请求流程
leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...
- zookeeper源码分析之四服务端(单机)处理请求流程
上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...
- zookeeper源码分析之三客户端发送请求流程
znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个功能是zookeeper对于应用最重要的特性,通过这个特性可以实现的功能包括配置的 ...
- java使用websocket,并且获取HttpSession,源码分析
转载请在页首注明作者与出处 http://www.cnblogs.com/zhuxiaojie/p/6238826.html 一:本文使用范围 此文不仅仅局限于spring boot,普通的sprin ...
随机推荐
- html中设置height=100%无效的问题
设置height=100%(网页内容能够更好的适配各种屏幕大小) 第一种是设置某个单独的div元素 height=100%无效 原因很简单,所有基于本分比的尺寸必须基于父元素,而你如果没有设置父元 ...
- 【ES6】对象的新功能与解构赋值
ES6 通过字面量语法扩展.新增方法.改进原型等多种方式加强对象的使用,并通过解构简化对象的数据提取过程. 一.字面量语法扩展 在 ES6 模式下使用字面量创建对象更加简洁,对于对象属性来说,属性初始 ...
- ModelForm操作
ModelForm a. class Meta: model, # 对应Model的 fields=None, # 字段 exclude=None, # 排除字段 labels=None, # 提示信 ...
- 【学习总结】快速上手Linux玩转典型应用-第7章-WebServer安装和配置讲解
课程目录链接 快速上手Linux玩转典型应用-目录 目录 1. Apache的安装 2. Apache的虚拟主机配置及伪静态操作 3. Nginx的基本操作 4. Nginx伪静态的实现 5. 实例演 ...
- oracle比较两个查询结果的差异
可以使用minus select * from A minus select * from B; select * from B minus select * from A;
- CF1103C Johnny Solving (Codeforces Round #534 (Div. 1)) 思维+构造
题目传送门 https://codeforces.com/contest/1103/problem/C 题解 这个题还算一个有难度的不错的题目吧. 题目给出了两种回答方式: 找出一条长度 \(\geq ...
- IO操作基本步骤
package com.study02; import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundE ...
- 基于flask的可视化动漫分析网站【python入门必学】
课程设计项目名称:基于flask的可视化动漫分析网站,如果你在学习Python的过程中,往往因为没有好的教程或者没人指导从而导致自己容易放弃,为此我建了个Python交流.裙 :一久武其而而流一思(数 ...
- 使用HTML和CSS来实现为文字设置图片底纹
先看一下最终实现的效果 图中的hello是文本而不是图片 那么如何实现这种效果呢? HTML部分: 创建一个h1标签 ,标签内容为(hello).通过link标签链接外部样式表style.css. s ...
- 超大文件上传方案(ASP.NET)
ASP.NET上传文件用FileUpLoad就可以,但是对文件夹的操作却不能用FileUpLoad来实现. 下面这个示例便是使用ASP.NET来实现上传文件夹并对文件夹进行压缩以及解压. ASP.NE ...