是否可以将Unsafe.CompareAndSwap与内存位置相对而使用对象的偏移量?

时间:2016-03-15 21:21:05

标签: java

大多数不安全操作都接受内存位置以执行操作 - 例如:

    Unsafe unsafe = Context.unsafe;
    long position = unsafe.allocateMemory(8);
    unsafe.putLong(position, 0);

然而,我所看到的CAS操作并没有提供这一点 - 他们将Object作为其中一个参数:

    unsafe.compareAndSwapLong(this, offset, expected, newvalue)

但是,考虑到处于“位置”位置的长度,如何在不是对象内的字段的情况下执行CAS操作?

1 个答案:

答案 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),因此它们可能使用相同的空对象处理逻辑。