JEP 193: Enhanced Volatiles

OwnerDoug Lea
Created2014/01/06 20:00
Updated2014/07/10 20:15
TypeFeature
StatusDraft
ScopeSE
JSRTBD
Discussioncore dash libs dash dev at openjdk dot java dot net
EffortM
DurationL
Priority4
Reviewed byDave Dice, Paul Sandoz
Endorsed byBrian Goetz
Issue8046183
DependsJEP 188: Java Memory Model Update

Summary

Define a way to invoke the equivalents of java.util.concurrent.atomic methods on object fields.

Motivation

As concurrent and parallel programming in Java continue to expand, programmers are increasingly frustrated by not being able to use Java constructions for arranging atomic or ordered operations for 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 JVM Unsafe intrinsics. Because intrinsics are preferable on performance grounds, their use has been increasingly common, 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.

Description

The target solution requires a syntax enhancement, a few library enhancements, and compiler support.

We model the extended operations on volatile integers via an interface VolatileInt, that also captures the functionality of AtomicInteger (which will also be updated to reflect Java Memory Model revisions as part of this JEP). A tentative version is below. Similar interfaces are needed for other primitive and reference types.

We then enable access to corresponding methods for fields using the .volatile prefix. For example:

class Usage {
    volatile int count;
    int incrementCount() {
        return count.volatile.incrementAndGet();
    }
}

The .volatile syntax is slightly unusual, but we are confident that it is syntactically unambiguous and semantically specifiable. New syntax is required to avoid ambiguities with existing usages, especially for volatile references -- invocations of methods on the reference versus the referent would be indistinguishable. The .volatile prefix introduces a scope for operations on these "L-values", not their retrieved contents. However, just using the prefix itself without a method invocation (as in count.volatile;) would be meaningless and illegal. We also expect to allow volatile operations on array elements in addition to fields. Enforcement of semantic restrictions (for example attempted usages for final fields) will require compiler support.

The main task is to translate these calls into corresponding JVM intrinsics. The most likely option is for the source compiler to use method handles. This and other techniques are known to suffice, but are subject to further exploration. Minor enhancements to intrinsics and a few additional JDK library methods may also be needed.

Here is a tentative VolatileInt interface. Those for other types are similar. The final released versions will surely differ, subject to the results of JEP 188.

interface VolatileInt {
    int get();
    int getRelaxed();
    int getAcquire();
    int getSequential();

    void set(int x);
    void setRelaxed(int x);
    void setRelease(int x);
    void setSequential(int x);

    int getAndSet(int x);
    boolean compareAndSet(int e, int x);
    boolean compareAndSetAcquire(int e, int x);
    boolean compareAndSetRelease(int e, int x);
    boolean weakCompareAndSet(int e, int x);
    boolean weakCompareAndSetAcquire(int e, int x);
    boolean weakCompareAndSetRelease(int e, int x);

    int getAndAdd(int x);
    int addAndGet(int x);
    int getAndIncrement();
    int incrementAndGet();
    int getAndDecrement();
    int decrementAndGet();
}

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

Alternatives

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 on java.util.concurrent.atomic FieldUpdaters, but their dynamic overhead and usage limitations make them unsuitable. 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.

Risks and Assumptions

We are confident of feasibility. However, we expect that it will require more experimentation to arrive at compilation techniques that result in efficient enough implementation for routine use in the performance-critical contexts where these constructs are most often needed. The use of method handles may be impacted by and may impact JVM method handle support.

Impact

A large number of usages in java.util.concurrent (and a few elsewhere in the JDK) could be simplified and updated to use this support.