[concurrency-interest] Double Checked Locking in OpenJDK

Vitaly Davidovich vitalyd at gmail.com
Wed Aug 15 21:51:13 EDT 2012


Exactly.  The key observation is that the write to "shared" cannot move
*before* the lock acquisition in the writer thread -- it can only either
stay after the monitor is released or move into the critical section; this
is because a monitor enter is just like a volatile read in JMM semantics,
which precludes subsequent stores (or loads, for that matter) from moving
before the monitor enter.  If this weren't the case, then we'd have a data
race again.  So the code as written is strange, but works :).

On Wed, Aug 15, 2012 at 9:42 PM, David Holmes <davidcholmes at aapt.net.au>wrote:

> Chris Povirk writes:
> >
> > Thanks, that's definitely part of the picture.  My memory-model
> > knowledge is very rusty, and it was never great, so here's one more
> > round of questions.  First, I'll spell out some in-thread
> > happens-before relationships:
> >
> > > local = new Vector();
> > > synchronized (local) {}
> > > shared = local;
> >
> > construction happens before synchronized block
> > synchronized block happens before write
> > (=> construction happens before write)
>
> Nope. construction happens-before end of synchronized block. write also
> happens-before end of synchronized block. roach-motel rules allow
> everything to be moved into the sync block.
>
> > > // other thread:
> > > local = shared;
> > > if (local != null) {
> > >   synchronized (local) {}
> > >   // safe to use local now?
> > > }
> >
> > read happens before synchronized block
> > synchronized block happens before use of local
> > (=> read happens before use of local)
>
> Again use of object could be moved inside the sync-block. But sync-block
> here can not be entered until after other thread releases the lock. So that
> establishes the happens-before ordering:
>
> everything in writer thread happens-before release of lock
> release of lock happens-before acquire of lock in second thread
> acquire of lock happens-before use of object
> => everything in writer thread happens-before use of object
>
> > The other thing that we want is for the write to happen before the
> > read.  If it does, then we have construction HB write HB read HB use,
> > and we're fine.  But the only cross-thread happens-before
> > relationships I can imagine are conditional: *If* the writer's
> > synchronized block happens before the reader's synchronized block,
> > then yes, construction happens before use.  But if the *reader*'s
> > synchronized block happens before the *writer*'s synchronized block,
> > then all bets are off.  Or does that somehow guarantee that *none* of
> > the writes from the writer thread are visible to the reader,
> > guaranteeing that the reader can't see an incompletely initialized
> > object by guaranteeing that it can't see the object at all?  Another
> > (more likely?) possibility is that the writer's synchronized block is
> > guaranteed to happen before the reader's, but I don't know enough
> > rules to justify that.  Or is there a third option?
>
> The above paragraph is confusing to me. The reader thread won't attempt to
> execute its sync block unless it sees the write to shared. The write to
> shared happens after the writer thread acquires the lock (and maybe after
> it releases it). So the reader will only attempt to acquire the lock once
> the writes have progressed to the point where shared was written, but it
> can't actually acquire the lock until all the writes are completed.
>
> Hope that clarifies.
>
> David
> -----
>
> > Thanks again.
> >
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120815/e6968e0f/attachment.html>


More information about the Concurrency-interest mailing list