Re: Mutable Objects and Thread Boundaries
Peter Duniho wrote:
It is worth noting that the reference to the object itself need not be
the thing that is subject to synchronization. Anything that
introduces the necessary memory barrier is sufficient.
One caveat here: "anything" must be the same thing in all threads which
access the shared data in question. If thread A locks objectA, and
thread B locks objectB, they are in no way synchronized, nor is there
any happens-before relationship establish for any shared data they access.
So, for example, any of the "storing a reference to it" examples above
are actually satisfied by any data being stored in the described
location, so long as the data being published has been initialized
prior to storage _and_ when the data is later read by a different
thread, that thread first retrieves whatever data was in fact stored
in the described location.
I don't think this is correct for all of the examples Joshua listed. For
example, storing a reference to a field that is properly guarded by a
lock does NOT create a happens-before relationship for "any data" later
read by a different thread.
Yes, it does. As long as the different thread reads the synchronized
data first (which is what I wrote).
Actually, the more I reread your statement, the more I'm sure I have no
idea what the heck you are actually trying to say. I can't think of any
combination of events where the events you listed actually bear on each
other. Could you produce an example where that's relevant?
private volatile boolean set = false;
private int data = 0;
data = 5;
set = true;
In the above example, if methodA() is executed on one thread, and then
methodB() is executed in a different thread, methodB() is guaranteed to
see the new value for "data".
Note that I didn't need to store the reference to the Test object
anywhere in order to ensure synchronization. I didn't need to store a
reference to _anything_, for that matter. It suffices to introduce the
partial memory barrier provided by the volatile write and read. All
writes that occur before the volatile write to a variable are guaranteed
to be visible in any other thread after it performs the volatile read
from the same variable.