AtomicReferenceFieldUpdater是基于反射的工具类,用来将指定类型的指定的volatile引用字段进行原子更新,对应的原子引用字段不能是private的。通常一个类volatile成员属性获取值、设定为某个值两个操作时非原子的,若想将其变为原子的,则可通过AtomicReferenceFieldUpdater来实现。如下面例子:

public class AtomicReferTest {
public static void main(String[] args) throws Exception
{
AtomicReferenceFieldUpdater updater=AtomicReferenceFieldUpdater.newUpdater(Dog.class,String.class,"name");
Dog dog1=new Dog();
System.out.println(updater.compareAndSet(dog1,"dog1","compareAndSet"));
System.out.println(dog1.name);
System.out.println(updater.getAndSet(dog1, "getAndSet"));
System.out.println(dog1.name);
}
}
class Dog
{
volatile String name="dog1"; }

输出结果:

true
compareAndSet
compareAndSet
getAndSet

通过调用AtomicReferenceFieldUpdater.newUpdater(Dog.class,String.class,"name")静态方法生成Dog类的String类型的name字段的原子修改器updater,然后调用它的compareAndSet方法判断dog1对象的name值是否为dog1,若是则返回true并修改其值。也可调用getAndSet方法直接修改dog1属性的name字段值,并返回该字段原来的值。

Java类库中BufferedInputStream就调用了这个类:

public
class BufferedInputStream extends FilterInputStream { protected volatile byte buf[]; /*
* 原子的更新内部数组,比如扩容、关闭时,
*/
private static final
AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
AtomicReferenceFieldUpdater.newUpdater
(BufferedInputStream.class, byte[].class, "buf"); public void close() throws IOException {
byte[] buffer;
while ( (buffer = buf) != null) {
//放在一个循环中,如果CAS更新失败,那么就读取最新的buf引用,继续CAS更新
if (bufUpdater.compareAndSet(this, buffer, null)) {
InputStream input = in;
in = null;
if (input != null)
input.close();
return;
}
}
}
}

AtomicReferenceFieldUpdater是Doug Lea在Java 5中写的atomic classes 中Filed Updater的一部分,本质上是volatile字段的包装器。相似的还有AtomicIntegerFieldUpdater,具体使用方法可参考:https://github.com/aCoder2013/blog/issues/10

注意原子更新器的使用存在比较苛刻的条件如下

  • 操作的字段不能是static类型。

  • 操作的字段不能是final类型的,因为final根本没法修改。

  • 字段必须是volatile修饰的,也就是数据本身是读一致的。

  • 属性必须对当前的Updater所在的区域是可见的,如果不是当前类内部进行原子更新器操作不能使用private,protected子类操作父类时修饰符必须是protect权限及以上,如果在同一个package下则必须是default权限及以上,也就是说无论何时都应该保证操作类与被操作类间的可见性。

Java并发编程-无锁CAS与Unsafe类及其并发包Atomic

Java原子属性更新器AtomicReferenceFieldUpdater的使用的更多相关文章

  1. 全面了解 Java 原子变量类

    目录   一.原子变量类简介  二.基本类型  三.引用类型  四.数组类型  五.属性更新器类型  参考资料

  2. 原子类型字段更新器AtomicXxxxFieldUpdater

    本博客系列是学习并发编程过程中的记录总结.由于文章比较多,写的时间也比较散,所以我整理了个目录贴(传送门),方便查阅. 并发编程系列博客传送门 原子类型字段更新器 在java.util.concurr ...

  3. Java操作属性文件,支持新增或更新多个属性

    Java操作属性文件.支持新增或更新多个属性 一.更新或新增单个属性的方法 /** * 写入properties信息 * @param filePath 绝对路径(包含文件名称和后缀名) * @par ...

  4. java自定义注解知识实例及SSH框架下,拦截器中无法获得java注解属性值的问题

    一.java自定义注解相关知识 注解这东西是java语言本身就带有的功能特点,于struts,hibernate,spring这三个框架无关.使用得当特别方便.基于注解的xml文件配置方式也受到人们的 ...

  5. Java多线程的下载器(1)

    实现了一个基于Java多线程的下载器,可提供的功能有: 1. 对文件使用多线程下载,并显示每时刻的下载速度. 2. 对多个下载进行管理,包括线程调度,内存管理等. 一:单个文件下载的管理 1. 单文件 ...

  6. 11大Java开源中文分词器的使用方法和分词效果对比,当前几个主要的Lucene中文分词器的比较

    本文的目标有两个: 1.学会使用11大Java开源中文分词器 2.对比分析11大Java开源中文分词器的分词效果 本文给出了11大Java开源中文分词的使用方法以及分词结果对比代码,至于效果哪个好,那 ...

  7. Java基础之类加载器

    Java类加载器是用户程序和JVM虚拟机之间的桥梁,在Java程序中起了至关重要的作用,理解它有利于我们写出更优雅的程序.本文首先介绍了Java虚拟机加载程序的过程,简述了Java类加载器的加载方式( ...

  8. Java中的类加载器

    转载:http://blog.csdn.net/zhangjg_blog/article/details/16102131 从java的动态性到类加载机制   我们知道,Java是一种动态语言.那么怎 ...

  9. 如何修改3D模型的原子属性

    Chem3D是专门用于绘制化学三维模型和进行计算化学数据的ChemOffice组件,在三维模型中每个原子都有众多属性,比如原子类型.原子符号.原子编号以及原子颜色等等.掌握Chem 3D模型的原子属性 ...

随机推荐

  1. Python基础语法01

    Python 标识符 在python里,标识符有字母.数字.下划线组成. 在python中,所有标识符可以包括英文.数字以及下划线(_),但不能以数字开头. python中的标识符是区分大小写的. 以 ...

  2. 树状数组求最大值 (RMQ with Shifts)

    代码: #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib ...

  3. 转:Hadoop和Spark的异同

    转自:http://www.techweb.com.cn/network/system/2016-01-25/2267414.shtml 谈到大数据,相信大家对Hadoop和Apache Spark这 ...

  4. uva 1378 - A Funny Stone Game sg博弈

    题意:David 玩一个石子游戏. 游戏中,有n堆石子,被编号为0..n-1.两名玩家轮流取石子. 每一轮游戏.每名玩家选取3堆石子i,j,k(i<j,j<=k,且至少有一枚石子在第i堆石 ...

  5. asp.net MVC通用分页组件 使用方便 通用性强

    asp.net MVC通用分页组件 使用方便 通用性强   该分页控件的显示逻辑: 1 当前页面反色突出显示,链接不可点击 2 第一页时首页链接不可点击 3 最后一页时尾页链接不可点击 4 当前页面左 ...

  6. 用户'sa'登录失败(错误18456)解决方案图解

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://thenear.blog.51cto.com/4686262/865544 htt ...

  7. Django-ondelete

    on_delete=None, # 删除关联表中的数据时,当前表与其关联的field的行为 on_delete=models.CASCADE, # 删除关联数据,与之关联也删除 on_delete=m ...

  8. WWDC2014苹果的“软件”发布会

    WWDC 2014 苹果的"软件"发布会 在今年的 6 月 2 日到 6 日,苹果照例举行了一年一次的全球开发者大会(World Wide Developer Conference ...

  9. php pack()函数详解与示例

    pack和unpack在一般的程序中还真的不容易见到,但是如果你用过很久以前的php生成excel你就会知道了.他的excel的头就是pack出来的最近在尝试与C交互的时候又用上了这玩意,所以不得不再 ...

  10. ReboletricSample工程搭建

    受到  Just Say No to More End-to-End Tests 文章链接:http://googletesting.blogspot.tw/2015/04/just-say-no-t ...