Re: Thread safety and atomic assignment (again)
"Philipp" <sicsicsic@freesurf.ch> wrote in message
news:1209559089_4017@sicinfo3.epfl.ch...
Hello,
By searching the web I found lots of references about the below question.
At the same time, I couldn't find an *authoritative* references (eg. by
Goetz, Lea or Bloch) about it. Please refer me to the correct web site or
book. Thanks (I'm using JVM 1.3, so the "old" memory model)
I find the best summary to be Doug Lea's "Concurrent Programming..." p.
92-97, which he says he takes from the JLS chapter 17 on the memory model.
My 2nd edition (C) 2000 copy says that this section is still being updated
for Java 2, so it is likely to be reasonably "authoritative" for 1.3.
However, he points out (and I have read from others) that the early memory
model is unclear in some places (p. 95 footnote) and downright broken in
others. And regardless of what is authoritatively written, any given JVM of
that vintage may or may not be implemented perfectly.
The question: Are the following code snippets thread safe and why? (my
opinion is on top, please correct if wrong):
// Not thread safe. "value" needs to be volatile, else another thread
// might see a stale value
public final class Test1 {
private int value = 0;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
According to Paul Hyde's Java Thread Programming p. 127, "Before Sun
included JIT with their VMs, volatile did not make a difference."
Nevertheless, if this code is accessed from threads that are not otherwise
synchronized, the lack of volatile may cause setValues in thread to not be
visible to another. The volatile keyword is sufficient to fix that because
the accesses and updates to the value are independent. If the code had
expressions such as value = value * 4 or value++, these must be sychronized
because they will appear as two or more independent operations. As long as
the access or updates are recognized to be totally independent, volatile is
acceptable.
// Not thread safe. Because assignment to long is not atomic (although //
volatile).
public final class Test2 {
private volatile long value = 0;
public long getValue() {
return value;
}
public void setValue(long value) {
this.value = value;
}
}
Doug Lea also asserts on p.93 that "atomicity extends to volatilie long and
double" even though they are not atomic when not volatile.
The next two cases are similar. They are threadsafe only to the extent that
the object reference is being updated in a timely and atomic way. There is
no guarantee of timely update for any fields of the assigned String or Date
and only their initial value will be visible. I'm not sure what counts as
"initial value" in this case, being that String and Date both assign most of
their fields in the constructor. This may be the uncertainty in the JLS that
Doug Lea talks about on p. 95.
As a clearer example of this point, if the object used for setValue had
non-volatile fields that were not assigned in the constructor, there is
nothing that guarantees that the updated values of those fields will be
visible in a different thread.
Matt Humphrey http://www.iviz.com/