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
网友评论