String.hashCode() in beta1 has intentional data race,
which is a good example of how a program can be
incorrectly-synchronized (according to the JMM), and
still be valid.
private int hash; // Default to 0
public int hashCode() {
int h = hash;
if (h == 0) {
h = ...
hash = h;
}
return h;
}
Since the sources of Java are the #1 place to learn
Java, I think that this trick should be documented in
the code. Specifically:
1. The code is not correctly synchronized according to
the JMM.
2. It is done this way since volatile reads/writes
costs much more.
3. Each thread at will calculate the hash at most once
(the happens-before edge from the initialization to
the first write of each thread ensures that).
4. It would not work for long / double.
5. It would not work for objects, unless they are
immutable (all fields are final).
6. The hash value 0 is sacrificed. There is no way to
sacrifice a different value (by adding initializer),
or not to sacrifice any value at all (by adding a
boolean variable).
7. The code cannot be changed to (on volatile, it
could, although not recommended):
if (hash != 0) return hash;
Doron.
=====
Doron Rajwan, mailto:doron@rajwan.org
-------------------------------
JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:01:04 EDT