JEP 193: Enhanced Volatiles

AuthorDoug Lea
OwnerPaul Sandoz
Created2014/01/06 20:00
Updated2015/05/19 16:17
Discussioncore dash libs dash dev at openjdk dot java dot net
Reviewed byDave Dice, Paul Sandoz
Endorsed byBrian Goetz
DependsJEP 188: Java Memory Model Update


Define a standard means to invoke the equivalents of java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements.


The following are required goals:

It is desirable, but not required, that the API be as good as the java.util.concurrent.atomic API.


As concurrent and parallel programming in Java continue to expand, programmers are increasingly frustrated by not being able to use Java constructs to arrange atomic or ordered operations on the fields of individual classes; for example, atomically incrementing a count field. Until now the only ways to achieve these effects were to use a stand-alone AtomicInteger (adding both space overhead and additional concurrency issues to manage indirection) or, in some situations, to use atomic FieldUpdaters (often encountering more overhead than the operation itself), or to use the unsafe (and unportable and unsupported) sun.misc.Unsafe API for JVM intrinsics. Intrinsics are faster, so they have become widely used, to the detriment of safety and portability. Without this JEP, these problems are expected to become worse as atomic APIs expand to cover additional access-consistency policies (aligned with the recent C++11 memory model) as part of Java Memory Model revisions.


This proposal focuses on the control of atomicity and ordering for single variables. We expect the resulting specifications to be extensible in natural ways to additional primitive-like value types or additional array-like types, if they are ever added to Java. This is not, however, a general-purpose transaction mechanism for controlling accesses and updates to multiple variables. Alternative forms for expressing and implementing such constructs may be explored in the course of this JEP, and may be the subject of further JEPs.

The target solution may require library enhancement, HotSpot enhancements, and compiler support. Language syntax enhancements may also be considered, especially if they enhance compile-time type checking and complement existing syntax.

We model the operations on reference and primitive types via an abstract class called VarHandle that contains one signature-polymorphic-like method for each operation. Such a class can support access to static fields, instance fields, and array elements for both reference types and primitive types. As such, VarHandles can be considered "MethodHandles for data".

A possible VarHandle class is:

public abstract class VarHandle {
    public abstract Object get(Object... args);
    public abstract Object getRelaxed(Object... args);
    public abstract Object getAcquire(Object... args);
    public abstract Object getSequential(Object... args);

    public abstract void set(Object... args);
    public abstract void setRelaxed(Object... args);
    public abstract void setRelease(Object... args);
    public abstract void setSequential(Object... args);

    public abstract Object getAndSet(Object... args);
    public abstract boolean compareAndSet(Object... args);
    public abstract boolean compareAndSetAcquire(Object... args);
    public abstract boolean compareAndSetRelease(Object... args);
    public abstract boolean weakCompareAndSet(Object... args);
    public abstract boolean weakCompareAndSetAcquire(Object... args);
    public abstract boolean weakCompareAndSetRelease(Object... args);

    public abstract Object getAndAdd(Object... args);
    public abstract Object addAndGet(Object... args);
    public abstract Object getAndIncrement(Object... args);
    public abstract Object incrementAndGet(Object... args);
    public abstract Object getAndDecrement(Object... args);
    public abstract Object decrementAndGet(Object... args);

The lookup of a VarHandle that accesses a field will, before producing and returning the VarHandle, perform the exact same access control checks (on behalf of the lookup class) as those performed by the lookup up of a MethodHandle that gives read and write access to that same field (see the find{,Static}{Getter,Setter} methods in the MethodHandles.Lookup class).

Such lookup to obtain a VarHandle covering a field named i of type int on a receiver class Foo might be performed as follows:

class Foo {
    int i;



class Bar {
    static final VarHandle VH_FOO_FIELD_I;

    static {
        try {
            VH_FOO_FIELD_I = VarHandles.lookup().
                findField(Foo.class, "i", int.class);
        } catch (Exception e) {
            throw new Error(e);

The number of arguments, the argument types, and return type of a 'VarHandle' instance are governed by what variable the VarHandle covers and what method is being invoked.

For example, a compareAndSet on the previously-looked up fooi handle requires 3 arguments, an instance of receiver Foo and two ints for the expected and actual values:

Foo f = ...
boolean r = VH_FOO_FIELD_I.compareAndSet(f, 0, 1);

In contrast, a getAndSet requires 2 arguments, an instance of receiver Foo and one int that is the value to be set:

int o = (int) VH_FOO_FIELD_I.getAndSet(f, 2);

Access to array elements will require an additional argument, of type int, between the receiver and value arguments (if any), that corresponds to the array index of the element to be operated upon.

It is important to optimize the VarHandle method invocation call-sites to avoid the overheads of boxing primitive arguments and packing all arguments into an array. Additionally, it is also important to guarantee that the HotSpot runtime (C2) compiler will inline those invocations and produce efficient machine code when appropriate conditions are met. (One such condition is the VarHandle instance should be a constant, as when held in a static final field, so constant folding will occur, such as folding away method-signature checks and/or receiver/value argument cast checks.)

Two possible solutions to avoid boxing and packing are:

  1. The VarHandle methods are declared to be signature polymorphic with minor enhancements on signature polymorphism to support non-polymorphic return types; or

  2. The Java compiler compiles VarHandle methods invocations into invokedynamic instructions, producing the same signature polymorphic method signatures as in 1), but crucially having the same semantics as ordinarily-generated invokevirtual instructions.

Note: the former is essentially a form of hard-coded invokedynamic which is currently specific to MethodHandles and is leveraged by invokedynamic. The properties of either should be roughly equivalent in terms of optimization.

Updates to the Java Virtual Machine Specification and the Java Language Specification (JLS) may be required to specify refinements to signature polymorphism and the addition of new signature-polymorphic methods.

A disadvantage of the explicit lookup of a VarHandle and leveraging "varargs" signature-polymorphic methods is the lack of static type checking to catch errors at compile time. Two possible improvements are further described.

The first improvement is to introduce, perhaps in conjunction with VarHandle, two generic classes, FieldHandle<R, V> and ArrayHandle<A, I, V>:

public abstract class FieldHandle<R, V> {
    public abstract V getAndSet(R r, V v);
    public abstract boolean compareAndSet(R r, V e, V a);

class ArrayHandle<R, I, V> {
    public abstract V getAndSet(R r, I i, V v);
    public abstract boolean compareAndSet(R r, I i, V e, V a);

Constrained method-signature polymorphism is applied to arguments associated with type variables that can be resolved to boxed types, such as Integer. This approach requires further careful analysis to ascertain if it is applicable in the short term while not causing issues in the long term if/when generics-over-primitives JEP 218 and value types are introduced. Furthermore, although out of scope for this JEP, usages of VarHandle, FieldHandle, or ArrayHandle in polymorphic or generic code should be anticipated.

A FieldHandle<R, V> instance can cover both instance and static fields. If the latter then the receiver argument is ignored and may be null, but would still be verified.

An ArrayHandle<A, I, V> may cover various array representations since the array type and the index type are generic (the latter declared as type variable I). For existing Java arrays, I will correspond to Integer and int indexes can be used. For alternative array representations (perhaps an off-heap pointer or an enhancement to existing arrays) I may correspond to Long and long index values. Further investigation will be required for multi-index configurations and potential integration with Arrays 2.0 (Note: I could correspond to an int[] array or, more preferably when value types are available, a kind of tuple type.)

The second improvement is a language syntax enhancement, leveraging the syntax for method references to look up a VarHandle (and a FieldHandle and ArrayHandle). For example, the previous lookup of a field 'i' on receiver class Foo could be expressed as follows:

 static final VarHandle VH_FOO_FIELD_I = Foo::i;

Note: this same syntax may also be used to lookup a java.lang.Field or a MethodHandle since the target type defines what field representation to look up.

Further investigation is required to determine the compilation strategy. The Java compiler might compile this to the explicit lookup-method calls (and manage possible exceptions). Alternatively this could be compiled to an invokedynamic instruction where it may be possible to better guarantee the return of a constant instance (in combination with a final local variable).


We considered instead introducing new forms of "value type" that support volatile operations. However, this would be inconsistent with properties of other types, and would also require more effort for programmers to use. We also considered expanding reliance upon java.util.concurrent.atomic FieldUpdaters, but their dynamic overhead and usage limitations make them unsuitable.

Syntax enhancements were considered in a previous version of this JEP but were deemed too "magical", with the overloaded use of the volatile keyword scoping to floating interfaces, one for references and one for each supported primitive type.

Several other alternatives, including those based on field references, have been raised and dismissed as unworkable on syntactic, efficiency, and/or usability grounds over the many years that these issues have been discussed.


Stress tests will be developed using the jcstress harness.

Risks and Assumptions

A prototype implementation of VarHandle has been performance-tested with nano-benchmarks and fork/join benchmarks, where the fork/join library's use of sun.misc.Unsafe was replaced with VarHandle. No major performance issues have been observed so far, and the HotSpot compiler issues identified do not seem onerous (folding cast checks and strength reducing array bounds checks). We are therefore confident of the feasibility of this approach. However, we expect that it will require more experimentation to ensure the compilation techniques are reliable in the performance-critical contexts where these constructs are most often needed.


The classes in java.util.concurrent (and other areas identified in the JDK) will be migrated from sun.misc.Unsafe to VarHandle.

This JEP depends on JEP 188: Java Memory Model Update.