从AtomicLong
的源代码:
public final boolean compareAndSet(long expect, long update) {
return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
}
从
AtomicLongFieldUpdater
的源代码: public static <U> AtomicLongFieldUpdater<U> newUpdater(Class<U> tclass,
String fieldName) {
Class<?> caller = Reflection.getCallerClass();
if (AtomicLong.VM_SUPPORTS_LONG_CAS)
return new CASUpdater<U>(tclass, fieldName, caller);
else
return new LockedUpdater<U>(tclass, fieldName, caller);
}
// CASUpdater extends AtomicLongFieldUpdater
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
return U.compareAndSwapLong(obj, offset, expect, update);
}
// LockedUpdater extends AtomicLongFieldUpdater
public final boolean compareAndSet(T obj, long expect, long update) {
accessCheck(obj);
synchronized (this) {
long v = U.getLong(obj, offset);
if (v != expect)
return false;
U.putLong(obj, offset, update);
return true;
}
}
我的问题是为什么两个类使用不同的方法来更新long值?即为什么
AtomicLongFieldUpdater
有条件地回退到锁定方法,而AtomicLong
没有? 最佳答案
这两个类基本上具有相同的目的,它们都使用内部的Unsafe
类来完成“硬性低级”工作。因此,质疑实现差异是合乎逻辑的。
我想在AtomicLongFieldUpdater
中完成的回退可能只是一个遗物。在VM_SUPPORTS_LONG_CAS
中定义了AtomicLong
但仅在AtomicLongFieldUpdater
中使用了AtomicLongFieldUpdater
这一事实可以证明这一点。
另一个可能性是Java作者决定对性能进行某种程度的优化,但他们只是在VM_SUPPORTS_LONG_CAS
中做到了。
答案可能隐藏在的javadoc中:
/**
* Records whether the underlying JVM supports lockless
* compareAndSwap for longs. While the Unsafe.compareAndSwapLong
* method works in either case, some constructions should be
* handled at Java level to avoid locking user-visible locks.
*/
static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
恐怕我们将不得不直接请作者知道确切的推理和含义。看来Java 5中已经有几乎相同的代码了-请参阅OpenJDK从2007年的“初始加载”提交中的source code。我认为很难在此代码之前进行提交...