David,
Answering your question from a programmer's perspective:
If the field in question is one of the primitive types that can be set
atomically, then you don't need to lock on read *if* you don't care
about stale values. (More of a "peek" than a "read" then...)
In fact, you may not need to lock at all in this case, except I'd wonder
about the optimizations an aggressive compiler/runtime might attempt.
(The JVM may ponder questions such as "If a field is assigned in the
woods.." and "What is the sound of one lock clicking?" - and its
conclusions may surprise you.)
If the field is a "long" or a "double", which are the primitive types
that aren't updated atomically, then declaring the field "volatile"
should fix the problem (without any locking), but many current JVM
implementations are broken.
The biggest problems occur when the field is an object reference. The
JMM *should* guarantee that the reader will see all writes made during
the construction of the object (right?). But what if the object is
constructed with a factory-style procedure, such as
Bean bean = new Bean();
bean.setFoo(3);
bean.setBar(4);
other.setBean(bean);
Will the reader of other.getBean() see the bean in its intended state?
The simplest example involves a field of array type:
int[] a = new int[2];
a[0] = 1;
a[1] = 2;
other.setA(a);
Will the reader of other.getA() see the array in the intended state? It
depends. Will the writes to main memory be performed in exactly the
order they are written?
Without synchronization of both reader and writer, there's no guarantee.
In fact, the object reference may be written before any of the
assignments are written, in which case the reader would see all '0's.
This is why the double-check idiom is not guaranteed to work even under
the new JMM.
As Jeremy says [just received the message], it has been *proposed* that
volatile be strengthened in order to fix this.
-- Joe Bowbeer----- Original Message ----- From: "David W. Smiley" <dsmiley@mitre.org> To: "Thomas Wang" <wang@cup.hp.com> Cc: <javaMemoryModel@cs.umd.edu> Sent: Tuesday, September 05, 2000 12:19 PM Subject: Re: JavaMemoryModel: re: Threading issues in my connection pool
FYI, my perspective of these matters comes from that of a Java programmer; not one who builds JVMs :-). Some of these term and concepts are new to me (ex: difference between "load" and "read").
Thomas Wang wrote: > > David, > > >There are a few techniques I am using to avoid synchronization: > >double check idiom > >copy on write ... > Now, only synchronize on update, and not synchronizing on read is a problem, > because the reader can read old or intermediate results. Some of the > Java system library code is guilty of this practice.
For the sync on update; I mean that a method that is interested in changing something will grab the lock, examine the value, and then maybe change it. No sync on read means that the method that just wants to grab the value does just that. There is no possible chance of intermediate results as I see it because there is only one field value being retrieved. I understand that a thread may call a getXXXX method and find a value that is slightly outdated because slightly before this time a _different_ thread changed it, but that is understandable. This pattern I just described is used in my JavaBean in which the lock locks the state (String instance used as a symbol); and there are many properties with getters and setters. So if my reasoning that everything is not okay as far as synchronization goes; please tell me what could go wrong.
> Double check idiom is probably hopeless- it doesn't even work in some > of current JVMs for single processor machine.
The hope is that it will one day once the JMM gets revised, right?
-- David Smiley
------------------------------- JavaMemoryModel mailing list - http://www.cs.umd.edu/~pugh/java/memoryModel
This archive was generated by hypermail 2b29 : Thu Oct 13 2005 - 07:00:27 EDT