API review of VarHandles

Aleksey Shipilev aleksey.shipilev at oracle.com
Fri Jan 22 13:06:09 UTC 2016


On 01/22/2016 03:08 PM, Vitaly Davidovich wrote:
> The VarHandle API isn't ergonomic like Unsafe; this being for power users
> is irrelevant to the ergonomics of the API.  Instead, it's fairly verbose
> with setup ceremony.  Now, I personally don't mind that too much and more
> interested in the features it provides but I'm not surprised by David's
> reaction.

Um, I don't get the "fairly verbose" and "setup ceremony" parts,
especially in comparison with Unsafe. Unsafe also comes with a setup
ceremony, don't you think?

See:

public class C {
  static class CU {
    static final Unsafe U;
    static final long OFFSET;

    static {
      try {
        Field f = Unsafe.class.getDeclaredField("theUnsafe");
        f.setAccessible(true);
        U = (Unsafe) f.get(null);
        OFFSET = U.objectFieldOffset(CU.class.getDeclaredField("x"));
      } catch (ReflectiveOperationException eh) {
        throw new IllegalStateException(eh);
      }
    }

    private int x;

    public boolean doCas(int expected, int value) {
      return U.compareAndSwapInt(this, OFFSET, expected, value);
    }
  }

  static class VU {
    static final VarHandle VH;

    static {
      try {
        VH = MethodHandles.lookup().findVarHandle(
                VU.class, "x", int.class);
      } catch (ReflectiveOperationException eh) {
        throw new IllegalStateException(eh);
      }
    }

    private int x;

    public boolean doCas(int expected, int value) {
      return VH.compareAndSet(this, expected, value);
    }
  }
}

Even if you pull off Unsafe lookup into separate "holder" class, you'd
still need to lookup OFFSET.

Granted, VH lookup requires learning new stuff, but so does Unsafe,
A*FU, Reflection, or any other special API/syntax. The mind trick is
that you already *know* all those APIs, and so they appear conceptually
simple to you. Once you internalize that VarHandle is a "handle", which
you have to acquire before use, it clicks.


> People already provide nicer APIs on top of Unsafe in their own projects,
> and I suspect this will be even more so with VH.

Yes, but lacking the syntax support, that's the best you can do:

 static class MyAwesomeWrapper {
   public static VarHandle iAmPrettySureThatFieldExists(
      MethodHandles.Lookup lookup, Class<?> recv, String name,
      Class<?> type) {
      try {
        return lookup.findVarHandle(recv, name, type);
      } catch (ReflectiveOperationException eh) {
        throw new IllegalStateException(eh);
      }
    }
  }

  static class VUH {
    static final VarHandle VH =
        MyAwesomeWrapper.iAmPrettySureThatFieldExists(
          MethodHandles.lookup(),
          VUH.class, "x", int.class);

    private int x;

    public boolean doCas(int expected, int value) {
      return VH.compareAndSet(this, expected, value);
    }
  }

...which is not that bad?

I am not discounting David's comments about the conceptual complexity of
the documentation. It looks like a normative text that 99% users would
not read, but stroll straight into code examples.

-Aleksey




More information about the core-libs-dev mailing list