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 ...
随机推荐
- 查看linux中所有用户的三种方式
通过使用/etc/passwd 文件,getent命令,compgen命令这三种方法查看系统中用户的信息. Linux 系统中用户信息存放在/etc/passwd文件中. 这是一个包含每个用户基本信息 ...
- Vue.nextTick浅析
Vue.nextTick浅析 Vue的特点之一就是响应式,但数据更新时,DOM并不会立即更新.当我们有一个业务场景,需要在DOM更新之后再执行一段代码时,可以借助nextTick实现.以下是来自官方文 ...
- sqlserver 创建 aspstate的方法
找到路径 C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727 不同版本找不同版本的路径 在命令行执行命令 aspnet_regsql.exe -ssadd -s ...
- 关于BeanUtils.copyProperties的用法和优缺点
一.简介: BeanUtils提供对Java反射和自省API的包装.其主要目的是利用反射机制对JavaBean的属性进行处理.我们知道,一个JavaBean通常包含了大量的属性,很多情况下,对Jav ...
- R语言multiplot函数绘制多张图像
必备数据包“Rmisc” 先准备好需要绘入的图像,以比如p1.p2表示, multiplot(p1, p2) 如果插入图像多,p1.p2.p3.p4,则需要规定图像排列顺序. multiplot(p1 ...
- python小实例
一.跳动的心 love = '\n'.join([''.join([('love'[(x-y) % len('Love')] if ((x*0.05)**2+(y*0.1)**2-1)**3-(x*0 ...
- 统计学习方法——第二章的c++实现
1.东西搞丢了,只写一部分 2.算法那收敛性 证明逻辑: a.γ是yi*(wopt*Xi)最小值 b.R是Xi最小值 c.k<=(R/γ)^2 难打公式,直接说,Wk由Wk-1迭代而来,所以事实 ...
- Taro -- Swiper的图片由小变大3d轮播效果
Swiper的图片由小变大3d轮播效果 this.state = ({ nowIdx:, swiperH:'', imgList:[ {img:'../../assets/12.jpg'}, {img ...
- Linux之bash的变量
1. 变量的显示,echo echo $变量 或 echo ${变量} eg. echo $HOME 或 echo ${HOME} 2. 变量的设置 变量的设置规则: (1)变量与变 ...
- flutter 布局简介
import 'package:flutter/material.dart'; class LayoutDemo extends StatelessWidget { @override Widget ...