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. Vue下简单分页及搜索功能

    最近利用Vue和element ui仿写了个小页面,记一哈分页和搜索功能的简单实现. 首页   emmmm..... 搜索框输入..... 搜索完成 数据是直接写在这里面的: cardPhoto:[ ...

  2. React全家桶入门

    http://blog.csdn.net/column/details/14545.html

  3. php 操作分表代码

    //哈希分表 function get_hash_table($table, $userid) { $str = crc32($userid); if ($str < 0) { $hash = ...

  4. 伟大的GIL

    GIL 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念.就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代 ...

  5. Python自动化学习--鼠标和键盘事件

    from selenium import webdriver from selenium.webdriver import ActionChains import time driver = webd ...

  6. 【转】内核中的内存申请:kmalloc、vmalloc、kzalloc、kcalloc、get_free_pages

    转自:https://www.cnblogs.com/yfz0/p/5829443.html 在内核模块中申请分配内存需要使用内核中的专用API:kmalloc.vmalloc.kzalloc.kca ...

  7. PAT Basic 1024 科学计数法 (20 分) Advanced 1073 Scientific Notation (20 分)

    科学计数法是科学家用来表示很大或很小的数字的一种方便的方法,其满足正则表达式 [+-][1-9].[0-9]+E[+-][0-9]+,即数字的整数部分只有 1 位,小数部分至少有 1 位,该数字及其指 ...

  8. Dinic二分图匹配 || Luogu P3386

    题面:[模板]二分图匹配 思路:Dinic实现二分图匹配,要建一个超级源点(S)和超级汇点(T),分别定为N+M+1和N+M+2 然后S去和N中的数建正边和反边,正边权值为1,反边权值为0:M中的数去 ...

  9. CentOS8 安装部署Apache+Php+MariaDB(pdo扩展)

    使用新的CentOS8系统架设PHP服务器,因现在主流数据库mysql已闭源了,所以现在改为使用MariaDB.而php7以后不支持mysqli链接,只有pdo方式,为了安装pdo扩展,所以重新编译安 ...

  10. Python3 install pip

    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/12033910.html curl https://bootstrap.pypa.io/get-pip. ...