来自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;
}
}我的问题是,为什么这两个类使用不同的方法来更新长值?也就是说,为什么AtomicLongFieldUpdater有条件地退回到锁定方法,而AtomicLong不呢?
发布于 2019-12-07 20:44:51
这两个类基本上服务于相同的目的,它们都使用内部Unsafe类来执行“硬的低级”工作。因此,唯一合乎逻辑的是质疑实现的差异。
我猜在AtomicLongFieldUpdater中所做的回退可能只是一个遗物。VM_SUPPORTS_LONG_CAS在AtomicLong中定义,但仅在AtomicLongFieldUpdater中使用,这一事实可以支持这一点。
另一种可能性是,Java作者决定在一定程度上优化性能,但他们只是在AtomicLongFieldUpdater中做到了这一点。
答案可能隐藏在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();我担心我们将不得不直接询问作者,以了解确切的推理和含义。似乎在Java5中已经有了几乎相同的代码-参见2007年OpenJDK的“初始加载”提交中的source code。我认为在这个之前很难提交...
https://stackoverflow.com/questions/59209313
复制相似问题