db-derby-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andreas Fredriksson <andreas.fredriks...@digitalroute.com>
Subject Re: Class loading deadlock
Date Thu, 15 Sep 2005 06:47:00 GMT
On Wed, 2005-09-14 at 09:18 -0700, Daniel John Debrunner wrote:
> Andreas Fredriksson wrote:

> Thanks for the patch, it may provide the correct approach but from a
> quick look the patch has some incorrect synchronization.
> 
> For example, this extract.
> 
> > +		synchronized (this) {
> > +			action = 2;
> > +		}
> 
> Synchronizing a single atomic action typically makes no sense, because
> as soon as the synchronization is released the state can change, in this
> case action could be modified. Synchronization involves ensuring
> *multiple* atomic actions occur in lock step, not a single atomic action.
> In this case the setting of the action variable needs to be synchronized
> with the priv block call, otherwise another thread could change action
> and thus change the behaviour of the call that the original thread was
> expecting.

I understand the reasoning, but to explain my point of view: if there's
no locking around the reading and writing of a primitive field, it's not
guaranteed that other threads see the value written unless the writer
thread has entered at least one monitor. The behavior depends on the
memory visibility parameters of the target platform whether readers see
the "old" or "new" value.

Since I was unsure about the locking patterns of calling code I
preserved the lock on the action field to avoid these problems--if the
calling pattern is such that it isn't a problem it can of course be
removed.

> As another general example, if I ever see code like this I know the
> coder maybe unclear on synchronization.
> 
> public synchronized int getCount()
> {
>      return count;
> }
> 
> The synchronization here doesn't guarantee anything, as soon as the
> method returns the count could change so the caller is only ever seeing
> a snapshot of the state, which is exactly what would happen if the
> method was not synchronized.

Yes, but see the above note. You're not guaranteed to see the _latest_
value written to that field, as per the Java Memory Model. If you
synchronize, you explicitly request to see the most recently visible
memory in that field, as flushed by other threads taking a lock.

Refer to
http://www-128.ibm.com/developerworks/java/library/j-jtp02244.html [
Java theory and practice: Fixing the Java Memory Model, Part 1] for a
summary of these issues.

What I'm getting at here is a special case; if you write a primitive
field from one thread without synchronization, and read it later on in
another thread without synchronization, there is a theoretical
possibility you will never see the written value in the second thread
because of the current memory visibility rules in Java.

In practice it doesn't happen in most code because a lot of calls are
synchronized and implicitly cause a memory barrier, but at our shop we
program defensively since our product deploys on systems with _many_
CPUs and with even laxer memory visibility and runs with uptime
guarantees.

Sorry for the lengthy bantering :-)

Regards,
Andreas


Mime
View raw message