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 源码分析的更多相关文章

  1. rxjava源码分析

    RXjava响应式编程 此文作者大暴雨原创,转载请注明出处. 如果线程的知识不是很丰富,请先查看     rxjava源码中的线程知识  一文 rxjava总结就是:异步实现主要是通过扩展观察者模式 ...

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

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

  3. Netty中NioEventLoopGroup的创建源码分析

    NioEventLoopGroup的无参构造: public NioEventLoopGroup() { this(0); } 调用了单参的构造: public NioEventLoopGroup(i ...

  4. spark 源码分析之十七 -- Spark磁盘存储剖析

    上篇文章 spark 源码分析之十六 -- Spark内存存储剖析 主要剖析了Spark 的内存存储.本篇文章主要剖析磁盘存储. 总述 磁盘存储相对比较简单,相关的类关系图如下: 我们先从依赖类 Di ...

  5. Netty中的ChannelPipeline源码分析

    ChannelPipeline在Netty中是用来处理请求的责任链,默认实现是DefaultChannelPipeline,其构造方法如下: private final Channel channel ...

  6. netty(六) buffer 源码分析

    问题 : netty的 ByteBuff 和传统的ByteBuff的区别是什么? HeapByteBuf 和 DirectByteBuf 的区别 ? HeapByteBuf : 使用堆内存,缺点 ,s ...

  7. spark源码分析以及优化

    第一章.spark源码分析之RDD四种依赖关系 一.RDD四种依赖关系 RDD四种依赖关系,分别是 ShuffleDependency.PrunDependency.RangeDependency和O ...

  8. Netty源码分析之ByteBuf引用计数

    引用计数是一种常用的内存管理机制,是指将资源的被引用次数保存起来,当被引用次数变为零时就将其释放的过程.Netty在4.x版本开始使用引用计数机制进行部分对象的管理,其实现思路并不是特别复杂,它主要涉 ...

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

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

随机推荐

  1. Python yield用法浅析(stackoverflow)

    这是stackoverflow上一个关于python中yield用法的帖子,这里翻译自投票最高的一个回答,原文链接 here 问题 Python中yield关键字的用途是什么?它有什么作用?例如,我试 ...

  2. xss过滤与单例模式(对象的实例永远用一个)

    kindeditor里面可以加入script代码,使用re可以过滤掉python有个专门的模块可以处理这种情况,beautifulsoup4 调用代码: content = XSSFilter().p ...

  3. ES6初步学习

    from:http://www.jianshu.com/p/287e0bb867ae 刚开始用vue或者react,很多时候我们都会把ES6这个大兄弟加入我们的技术栈中.但是ES6那么多那么多特性,我 ...

  4. Docker守护式容器的创建和登录

    创建守护式容器 如果对于一个需要长期运行的容器来说,我们可以创建一个守护式容器(后台运行的容器). 创建(-d)并运行(-i)守护式容器命令如下(容器名称不能重复): docker run -id - ...

  5. linux Apache 日志轮询

    安装日志轮询工具 cronolog [root@Nagios-Server tools]# wgethttp://cronolog.org/download/cronolog-1.6.2.tar.gz ...

  6. Screen.MousePointer 属性 (访问)

    可以使用鼠标指针以及屏幕对象属性可以指定或确定当前显示的鼠标指针的类型.读取/写入的整数. 语法     表达式.MousePointer 表达式 一个代表 Screen 对象的变量. 注解     ...

  7. linux extglob模式 和rm反选,除了某个文件外的其他文件全部删除的命令

    1.extglob模式开启之后Shell可以另外识别出5个模式匹配操作符,能使文件匹配更加方便. 不然不识别 #开启命令: shopt -s extglob #关闭命令: shopt -u extgl ...

  8. python添加清屏功能

    创建文件ClearWindow添加内容 class ClearWindow: menudefs = [ ('options', [None, ('Clear Shell Window', '<& ...

  9. 转 git 本地文件添加远程git

    好的博客膜拜一下 https://www.liaoxuefeng.com/wiki/896043488029600/898732864121440 现在的情景是,你已经在本地创建了一个Git仓库后,又 ...

  10. LOJ#2330 榕树之心 树形dp

    瞎扯 这个题和\(\mathsf{ISIJ2019 Au}\)神仙学弟\(\mathsf{\color{red}c}\mathsf{hangruinian2020}\)争辩了半个多小时. 概括一下就是 ...