AtomicIntegerFieldUpdater 源码分析
AtomicIntegerFieldUpdater
AtomicIntegerFieldUpdater 能解决什么问题?什么时候使用 AtomicIntegerFieldUpdater?
1)字段必须是 volatile 类型的实例变量。
2)调用者能够直接通过反射的方式操作对象字段,而不存在可见性问题。
如何使用 AtomicIntegerFieldUpdater?
1)指定对象的 int 值需要支持并发多读少写的场景下,使用 AtomicIntegerFieldUpdater。
使用 AtomicIntegerFieldUpdater 有什么风险?
1)高并发场景下,自旋 CAS 长时间失败会导致 CPU 飙升。
AtomicIntegerFieldUpdater 核心操作的实现原理?
创建实例
/**
* 基于指定的 Class 类型和字段名称创建一个 AtomicIntegerFieldUpdater 实例,
* 字段类型必须是 volatile int。
*/
@CallerSensitive
public static <U> AtomicIntegerFieldUpdater<U> newUpdater(Class<U> tclass,
String fieldName) {
return new AtomicIntegerFieldUpdaterImpl<U>
(tclass, fieldName, Reflection.getCallerClass());
}
尝试以原子的方式更新目标对象的 int 值
AtomicIntegerFieldUpdaterImpl#
@Override
public boolean compareAndSet(T obj, int expect, int update) {
accessCheck(obj);
return AtomicIntegerFieldUpdaterImpl.U.compareAndSetInt(obj, offset, expect, update);
}
获取此更新器管理的,在给定对象的字段中保持的当前值
AtomicIntegerFieldUpdaterImpl#
@Override
public int get(T obj) {
accessCheck(obj);
return AtomicIntegerFieldUpdaterImpl.U.getIntVolatile(obj, offset);
}
以原子方式将此更新器管理的给定对象的当前值 + 1,并返回旧值
AtomicIntegerFieldUpdaterImpl#
public final int getAndIncrement(T obj) {
return getAndAdd(obj, 1);
}
public final int getAndAdd(T obj, int delta) {
accessCheck(obj);
return U.getAndAddInt(obj, offset, delta);
}
/**
* 检查目标对象是否是指定 Class 类型的实例
*/
private void accessCheck(T obj) {
if (!cclass.isInstance(obj)) {
throwAccessCheckException(obj);
}
}
以原子方式将此更新器管理的给定对象的当前值 - 1,并返回旧值
AtomicIntegerFieldUpdaterImpl#
@Override
public int getAndDecrement(T obj) {
return getAndAdd(obj, -1);
}
以原子方式将此更新器管理的给定对象的当前值 + delta,并返回旧值
AtomicIntegerFieldUpdaterImpl#
@Override
public int getAndAdd(T obj, int delta) {
accessCheck(obj);
return AtomicIntegerFieldUpdaterImpl.U.getAndAddInt(obj, offset, delta);
}
以原子方式将此更新器管理的给定对象的当前值更新为一元函数式接口的计算值,并返回旧值
/**
* 以原子方式将此更新器管理的给定对象的当前值更新为一元函数式接口的计算值,并返回旧值
*/
public final int getAndUpdate(T obj, IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get(obj);
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(obj, prev, next));
return prev;
}
以原子方式将此更新器管理的给定对象的当前值更新为二元函数式接口的计算值,并返回旧值
/**
* 以原子方式将此更新器管理的给定对象的当前值更新为二元函数式接口的计算值,并返回旧值
*/
public final int getAndAccumulate(T obj, int x,
IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get(obj);
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(obj, prev, next));
return prev;
}
以原子方式将此更新器管理的给定对象的当前值 + 1,并返回新值
AtomicIntegerFieldUpdaterImpl#
@Override
public int incrementAndGet(T obj) {
return getAndAdd(obj, 1) + 1;
}
@Override
public int getAndAdd(T obj, int delta) {
accessCheck(obj);
return AtomicIntegerFieldUpdaterImpl.U.getAndAddInt(obj, offset, delta);
}
/**
* 检查目标对象是否是指定 Class 类型的实例
*/
private void accessCheck(T obj) {
if (!cclass.isInstance(obj)) {
throwAccessCheckException(obj);
}
}
以原子方式将此更新器管理的给定对象的当前值 - 1,并返回新值
AtomicIntegerFieldUpdaterImpl#
@Override
public int decrementAndGet(T obj) {
return getAndAdd(obj, -1) - 1;
}
以原子方式将此更新器管理的给定对象的当前值 + delta,并返回新值
AtomicIntegerFieldUpdaterImpl#
@Override
public int addAndGet(T obj, int delta) {
return getAndAdd(obj, delta) + delta;
}
以原子方式将此更新器管理的给定对象的当前值更新为一元函数式接口的计算值,并返回新值
/**
* 以原子方式将此更新器管理的给定对象的当前值更新为一元函数式接口的计算值,并返回新值
*/
public final int updateAndGet(T obj, IntUnaryOperator updateFunction) {
int prev, next;
do {
prev = get(obj);
next = updateFunction.applyAsInt(prev);
} while (!compareAndSet(obj, prev, next));
return next;
}
以原子方式将此更新器管理的给定对象的当前值更新为二元函数式接口的计算值,并返回新值
/**
* 以原子方式将此更新器管理的给定对象的当前值更新为二元函数式接口的计算值,并返回新值
*/
public final int accumulateAndGet(T obj, int x,
IntBinaryOperator accumulatorFunction) {
int prev, next;
do {
prev = get(obj);
next = accumulatorFunction.applyAsInt(prev, x);
} while (!compareAndSet(obj, prev, next));
return next;
}
AtomicIntegerFieldUpdater 源码分析的更多相关文章
- rxjava源码分析
RXjava响应式编程 此文作者大暴雨原创,转载请注明出处. 如果线程的知识不是很丰富,请先查看 rxjava源码中的线程知识 一文 rxjava总结就是:异步实现主要是通过扩展观察者模式 ...
- Java高并发之无锁与Atomic源码分析
目录 CAS原理 AtomicInteger Unsafe AtomicReference AtomicStampedReference AtomicIntegerArray AtomicIntege ...
- Netty中NioEventLoopGroup的创建源码分析
NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...
- spark 源码分析之十七 -- Spark磁盘存储剖析
上篇文章 spark 源码分析之十六 -- Spark内存存储剖析 主要剖析了Spark 的内存存储.本篇文章主要剖析磁盘存储. 总述 磁盘存储相对比较简单,相关的类关系图如下: 我们先从依赖类 Di ...
- Netty中的ChannelPipeline源码分析
ChannelPipeline在Netty中是用来处理请求的责任链,默认实现是DefaultChannelPipeline,其构造方法如下: private final Channel channel ...
- netty(六) buffer 源码分析
问题 : netty的 ByteBuff 和传统的ByteBuff的区别是什么? HeapByteBuf 和 DirectByteBuf 的区别 ? HeapByteBuf : 使用堆内存,缺点 ,s ...
- spark源码分析以及优化
第一章.spark源码分析之RDD四种依赖关系 一.RDD四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和O ...
- Netty源码分析之ByteBuf引用计数
引用计数是一种常用的内存管理机制,是指将资源的被引用次数保存起来,当被引用次数变为零时就将其释放的过程.Netty在4.x版本开始使用引用计数机制进行部分对象的管理,其实现思路并不是特别复杂,它主要涉 ...
- ABP源码分析一:整体项目结构及目录
ABP是一套非常优秀的web应用程序架构,适合用来搭建集中式架构的web应用程序. 整个Abp的Infrastructure是以Abp这个package为核心模块(core)+15个模块(module ...
随机推荐
- A - 卿学姐与公主(线段树+单点更新+区间极值)
A - 卿学姐与公主 Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Submi ...
- PHP批量导入excell表格到mysql数据库
PHP批量导入excell表格到mysql数据库,本人通过亲自测试,在这里分享给大家 1,下载 php excell类库 网上搜索可以下载,这里不写地址 2,建html文件 <form met ...
- PCIeの数据链路层与物理层详解
数据链路层(DLL,Data Link Layer)的主要作用是进行链路管理(Link Management).TLP错误校验.Flow Control(流控制)和Link功耗管理.不仅可以接收发送来 ...
- egg框架实现表单验证及获取验证的错误信息
最近再看egg框架 是阿里今年开源的一款基于nodejs的mvc架构的web框架 感兴趣的同学可以看看 因为之前一直做php的关系 在tp,yii,laravel这些框架中对于前台发送的数据,模型里都 ...
- react找到对象数组中指定的值
找到对象数组中指定的值var array = [ { label: "Custom", value: "0" }, ...
- 什么是CPC,CPA,CVR,CTR,ROI
合格的网络营销人员都应该熟悉下面的常见英文缩写,这些都是我们必须知道的名词解释:CVR (Click Value Rate): 转化率,衡量CPA广告效果的指标CTR (Click Through R ...
- Java List对象集合按对象属性分组、分组汇总、过滤等操作示例
import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Col ...
- IOS绘图详解(http://blog.163.com/wkyuyang_001/blog/static/10802122820133190545227/)
14.1 Quartz概述 Quartz是Mac OS X的Darwin核心之上的绘图层,有时候也认为是CoreGraphics.共有两种部分组成Quartz: Quartz Compositor,合 ...
- 028-实现阿里云ESC多FLAT网络
实现类似于阿里云ECS的网络结构,其效果为云主机拥有两块和两个不同的网络,一个网络是用于用于和外网连接,一个用于内网通信,但宿主机上至少有两个网卡,整体配置如下:1.在wmare里给宿主机添加一块网卡 ...
- windows用ffmpeg实现视频剪切
1.安装ffmpeg 从官网下载适合自己版本的FFmpeg,网址是http://ffmpeg.org/download.html,在get the packages中点击windows builds ...