大多数不安全操作都接受内存位置来执行操作 - 例如:
Unsafe unsafe = Context.unsafe;
long position = unsafe.allocateMemory(8);
unsafe.putLong(position, 0);
但是,据我所知,CAS 操作不提供此功能 - 它们而是将对象作为参数之一:
unsafe.compareAndSwapLong(this, offset, expected, newvalue)
但是,考虑到位于“position”位置的 long,如何在它不是对象内的字段的情况下执行 CAS 操作?
最佳答案
根据Unsafe.getInt(Object o, long offset)的文档:
Fetches a value from a given Java variable. More specifically, fetches a field or array element within the given object o at the given offset, or (if o is null) from the memory address whose numerical value is the given offset.
可能(我没有亲自测试过这一点)这同样适用于 compareAndSwapLong
,因此您可以尝试为 o
传递 null
并将 offset
设置为内存地址。
深入研究 native 代码,比较 compareAndSwapLong
的 code :
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapLong(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jlong e, jlong x))
UnsafeWrapper("Unsafe_CompareAndSwapLong");
Handle p (THREAD, JNIHandles::resolve(obj));
jlong* addr = (jlong*)(index_oop_from_field_offset_long(p(), offset));
...
和 getInt
的 code :
#define GET_FIELD(obj, offset, type_name, v) \
oop p = JNIHandles::resolve(obj); \
type_name v = *(type_name*)index_oop_from_field_offset_long(p, offset)
<小时/>
两者都使用JNIHandles::resolve(obj)
,因此它们可能使用相同的空对象处理逻辑。
关于java - 是否可以将 Unsafe.CompareAndSwap 与内存位置而不是对象的偏移量一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36022412/