思考:
需要回答用法与区别,最好有实例
AtomicReference用法
static class Hold {
AtomicReference<String> value = new AtomicReference<>();
}
//AtomicReference
Hold hold = new Hold();
hold.value.set("123");
hold.value.compareAndSet("123","456");
String val = hold.value.getAndUpdate(new UnaryOperator<String>() {
@Override
public String apply(String s) {
return "1233454";
}
});
System.out.println(val+"-"+hold.value.get());
AtomicReferenceFieldUpdater
static class Hold2{
public static AtomicReferenceFieldUpdater<Hold2,String> valueUpdate = AtomicReferenceFieldUpdater.newUpdater(Hold2.class,String.class,"val");
volatile String val = "val";
}
//AtomicReferenceFieldUpdater
Hold2 hold2 = new Hold2();
Hold2.valueUpdate.set(hold2,"123");
Hold2.valueUpdate.compareAndSet(hold2,"123","456");
String val = Hold2.valueUpdate.getAndUpdate(hold2, new UnaryOperator<String>() {
@Override
public String apply(String s) {
return "1233454";
}
});
System.out.println(val+"-"+Hold2.valueUpdate.get(hold2));
相同点和不同点
- 相同点 核心原子操作的原理基本一致,都是通过unsafe的CAS来实现,api使用也大同小异。
- 不同点 AtomicReference:使用更加直接,但是不宜大量创建,会有内存问题。 AtomicReferenceFieldUpdater:基于反射来使用,使用时静态变量形式出现,不会有AtomicReference的内存问题,大量框架和系统api中都有使用到。比如BufferedInputSteam,其内存更新byte[] 需要保证原子性。