大多数不安全操作都接受内存位置以执行操作 - 例如:
Unsafe unsafe = Context.unsafe;
long position = unsafe.allocateMemory(8);
unsafe.putLong(position, 0);
然而,我所看到的CAS操作并没有提供这一点 - 他们将Object作为其中一个参数:
unsafe.compareAndSwapLong(this, offset, expected, newvalue)
但是,考虑到处于“位置”位置的长度,如何在不是对象内的字段的情况下执行CAS操作?
答案 0 :(得分:2)
根据Unsafe.getInt(Object o, long offset)的文件:
从给定的Java变量中获取值。 更具体地说,获取给定的字段或数组元素 对象o在给定的偏移处,或(如果o是 从数据值给定的内存地址开始 偏移量。
可能(我还没有对此进行亲自测试)同样适用于compareAndSwapLong
,因此您可以尝试将null
传递给o
并使offset
成为记忆地址。
深入了解原生代码,比较compareAndSwapLong
' s 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
' s 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)
,因此它们可能使用相同的空对象处理逻辑。