[concurrency-interest] Double Checked Locking in OpenJDK

Zhong Yu zhong.j.yu at gmail.com
Wed Aug 15 22:05:11 EDT 2012


A more formal proof: we have 4 actions to consider here

sync1
write

read
sync2

(6 actions really - each sync contains lock+unlock)

Either sync1 is ordered before sync2, or sync2 before sync1. [1]

Suppose sync2 is ordered before sync1, there is hb(sync2,sync1),
therefore there is hb(read, write).  [2]

Therefore the read is not allowed to observed the write. [3]

The read must observe one of the writes. [4]

The only other write is the null-ing of the field. Therefore the read
must observe null. Which is contradictory to (local!=null)

Therefore it must be false that sync2 is ordered before sync1.

[1] http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.4
[2] http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5
[3] http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.5-500
[4] http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.4.7

Zhong Yu

On Wed, Aug 15, 2012 at 8:25 PM, Chris Povirk <cpovirk at google.com> wrote:
> 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)
>
>> // 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)
>
> 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?
>
> Thanks again.
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


More information about the Concurrency-interest mailing list