AtomicReferenceFieldUpdater是基于反射的工具類苇瓣,用來將指定類型的指定的volatile引用字段進行原子更新孝情,對應的原子引用字段不能是private的。通常一個類volatile成員屬性獲取值措拇、設定為某個值兩個操作時非原子的,若想將其變?yōu)樵拥模瑒t可通過AtomicReferenceFieldUpdater來實現(xiàn)问拘。如下面例子:
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")靜態(tài)方法生成Dog類的String類型的name字段的原子修改器updater,然后調用它的compareAndSet方法判斷dog1對象的name值是否為dog1惧所,若是則返回true并修改其值骤坐。也可調用getAndSet方法直接修改dog1屬性的name字段值,并返回該字段原來的值下愈。
Java類庫中BufferedInputStream就調用了這個類:
public class BufferedInputStream extends FilterInputStream { protected volatile byte buf[]; /* * 原子的更新內部數(shù)組纽绍,比如擴容、關閉時势似, */
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) { //放在一個循環(huán)中拌夏,如果CAS更新失敗,那么就讀取最新的buf引用履因,繼續(xù)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