JavaMemoryModel: Final and Volatile array classes

From: Doug Lea (
Date: Thu Mar 23 2000 - 07:21:02 EST

Nearly all of the decisions that I (and probably you) don't want to
have to make about final and volatile semantics surround the fact that
one cannot now declare that elements of an array are final or

This underlying problem could be fixed. But there are lots of
arguments for not changing the language syntax to do so. Instead, I'd
like to get on the table a proposal to create simple array-holding
classes with special semantics.

For volatile, here's the int version. (Seven others just like it
would be required: byte, short, char, long, float, double, Object.)

final class java.lang.VolatileIntArray {
  VolatileIntArray(int capacity); // initialize to all-zeros
  VolatileIntArray(int[] elements); // initialize as copy of array
  VolatileIntArray(int[] elements, int offset, int size); // sub-array version
  int length();
  int get(int i);
  void set(int i, int value);
  int[] toArray(); // return copy

The semantics are that initialization/get/set of each element acts in
the same way as read/write from a volatile field.

For final:

final class java.lang.FinalIntArray {
  FinalIntArray(int[] elements); // initialize as copy
  FinalIntArray(int[] elements, int offset, int size); // sub-array version
  int length();
  int get(int i);
  int[] toArray(); // return copy

The semantics are that initialization/get of each element acts in
the same way as a final field.

There are no multidimensional versions. People would have to
do this manually. It's not hard. For example:
  VolatileObjectArray matrix = new VolatileObjectArray(nrows);
  for (int i = 0; i < nrows; ++i)
    matrix.set(i, new VolatileFloatArray(ncols));

  (Element extraction would sometimes require ugly casts, but this may be
  addressed by generics proposal.)

All-in-all, this is not much less convenient to use than would
be special syntax for marking array elements as final or volatile.

Compilers would be required to have special knowledge of these
classes. In addition to properly maintaining semantics, this enables
some optimizations that will typically lead to them being just as fast
as raw arrays. In particular, they would not always need to make
array copies in constructors when they could determine that the
intialization arrays isn't otherwise used. And in many cases, they
could inline these objects as parts of their enclosing objects and
thus save on GC, indirection, etc overhead. And so on.

Some JDK classes would need to be rewritten to use this. Offhand
though, the number of classes for which this would be critical
seems pretty small. String, for sure.

The main advantages I can see for this approach are that the memory
model rules become easier to understand, implement, enforce, and agree

  1. The ordinary rules for final become the ones Bill listed
     as being uncontroversial:

        * If you read a final field, you are guaranteed to see the value set
          in the constructor unless:
          * The object escapes before the constructor finishes
          * The thread constructing the object reads the field before it is
          * Native code or reflection is used to change the field
        * This guarantee is enforced regardless of data races.

  2. The ordinary rules for volatile most likely become the ones
     associated with Bill's V1-V2; that is, no automatic propagation
     of volatileness down one or more levels of indirection.

The disadvantages I know of are:

  1. It would require revision of some core classes. (However,
     some revision seems inevitable in any case.)

  2. Just adding a "volatile" or "final" here and there would
     not fix as many existing broken programs as it would if
     the most liberal versions of final and volatile were adopted.

Any others? Are these compelling?

Doug Lea, Computer Science Department, SUNY Oswego, Oswego, NY 13126 USA 315-341-2688 FAX:315-341-5424  
JavaMemoryModel mailing list -

This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:24 EDT