java 设置原子属性_Java原子属性更新器AtomicReferenceFieldUpdater的使用

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

public classAtomicReferTest {public static void main(String[] args) throwsException

{

AtomicReferenceFieldUpdater updater=AtomicReferenceFieldUpdater.newUpdater(Dog.class,String.class,"name");

Dog dog1=newDog();

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);

}

}classDog

{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 extendsFilterInputStream {protected volatile bytebuf[];/** 原子的更新内部数组,比如扩容、关闭时,*/

private static finalAtomicReferenceFieldUpdater bufUpdater =AtomicReferenceFieldUpdater.newUpdater

(BufferedInputStream.class, byte[].class, "buf");public void close() throwsIOException {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权限及以上,也就是说无论何时都应该保证操作类与被操作类间的可见性。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值