[concurrency-interest] Double Checked Locking in OpenJDK

David Holmes davidcholmes at aapt.net.au
Wed Aug 15 19:33:41 EDT 2012


Typo:

I wrote:
>
> Ruslan Cheremin writes:
> >
> > > The reason to keep them distinct is because in general the
> > > mechanisms for safe publication are external to the class,
> > > while those for thread-safety are internal. It is only an
> > > edge case where use of synchronized in a constructor can
> > > achieve safe-publication.
> >
> > Well, actually I do not understand your point. If I use some kind of
> > synchronization to make methods of my object thread-safe -- can't I
> > also apply same thing to constructor? For me, it makes the thing only
> > clearer. Object can be thread-safe -- and it is totally thread safe.
> > Object can require external synchronization for correct multithreaded
> > use -- and it requires the sync for publishing and for usage also.
>
> You have to be able to establish the necessary happens-before
> relationships between the end of construction, publication and use.
>
> If thread-safe means you've created a "monitor" where only one method
> invocation can proceed at a time and all methods are synchronized, then
> synchronized in the constructor will construction happens-before use, and
> the publication mechanism is not relevant.

That should say "will _ensure_ construction happens-before use"

David


> If all your fields are final or volatile then you also have no issue with
> publication.
>
> Otherwise you have a bit more work to do. Relying on safe-publication to
> introduce the happens-before ordering allows you to use simpler, more
> natural, and likely more performant code in your thread-safe class.
>
> David
> -----
>
>
> > From my point of view, the distinction you talking about is more
> > historically reasoned. "Sync method if you want it to be thread-safe"
> > is commonly learned mantra, but "take care of initialization also" is
> > not so common. More information about it, more education, more
> > different code samples with outlined "here is the dragons" will change
> > the situation, I sure, it just have to be highlighted more often.
> >
> >
> > > People have to recognize that sharing an object requires
> shared mutable
> > > state, and the number one tenet of concurrent programming is
> > that access to
> > > shared mutable state has to be synchronized (in a general sense not
> > > specifically use of 'synchronized' keyword).
> > >
> > > Making every object safely publishable could be done, but for
> > 99% of objects
> > > it would be a waste of effort. Programs without data races
> > don't have issues
> > > with unsafe publication.
> > >
> > > David
> > >
> > > -----Original Message-----
> > > From: concurrency-interest-bounces at cs.oswego.edu
> > > [mailto:concurrency-interest-bounces at cs.oswego.edu]On Behalf Of Nathan
> > > Reynolds
> > > Sent: Wednesday, 15 August 2012 4:59 AM
> > > To: concurrency-interest at cs.oswego.edu
> > > Subject: Re: [concurrency-interest] Double Checked Locking in OpenJDK
> > >
> > > We seem to be splitting two notions (i.e thread-safe and safe
> > publication)
> > > when they should be combined in a sense.  Typically, when we
> > say thread-safe
> > > we talk about the operations performed on the object after it was
> > > constructed (and its contents are globally visible).  However,
> > we need to
> > > consider that executing the constructor is modifying the state of the
> > > object.  It requires the same mechanisms that the rest of the
> > class uses to
> > > ensure thread-safety.  Even though, there is only 1 thread
> executing the
> > > constructor, a proper releasing of a lock or some other happens-before
> > > construct is required to ensure that the memory updates by the
> > thread are
> > > made globally visible before the object is accessed by another
> > thread.  This
> > > is what we are calling safe publication.  So, safe publication
> > is a subset
> > > of thread-safety except it is limited to what happens after the
> > constructor
> > > is called and before the object is used by multiple threads.
> > >
> > > A beautifully-written class can be thread-safe with respect to
> > calling its
> > > member methods but not thread-safe with respect to calling its
> > constructor.
> > > It is this latter case that many stumble upon because they think that
> > > constructors are inherently thread-safe because they are executed
> > > single-threadedly.  What they fail to realize is that the
> execution of a
> > > constructor can overlap with the execution of other code from
> > the view point
> > > of what is happening in memory.  This same problem applies to
> > more rare case
> > > of regular methods which can be proven to execute in a single
> thread but
> > > don't use synchronization before multiple threads start
> > accessing the shared
> > > data.
> > >
> > > Nathan Reynolds | Consulting Member of Technical Staff | 602.333.9091
> > > Oracle PSR Engineering | Server Technology
> > > On 8/13/2012 4:08 PM, David Holmes wrote:
> > >
> > > Ruslan Cheremin writes:
> > >
> > > For me it is confusing: java has only one way to have really immutable
> > > object, and this way also gives you a total thread safety even for
> > > data race based publication. But then docs refer object as "immutable
> > > and thread-safe" -- we still can't assume it to be really thread-safe?
> > >
> > > It is better/simpler to isolate the notion of thread-safety and safe
> > > publication. Thread-safety comes into play after you have
> > safely shared an
> > > object. The means by which you safely share an object is
> > orthogonal to how
> > > the object itself is made thread-safe.
> > >
> > > The means by which an object is shared has to involve shared
> > mutable state,
> > > and use of shared mutable state always needs some form of
> > synchronization
> > > (either implicit eg due to static initialization; or explicit by using
> > > volatile or synchronized getter/setter methods).
> > >
> > > David
> > > -----
> > >
> > > It's a pity, especially because true immutability gives us some
> > > chances of performance optimization. As in this case -- we do not
> > > really need .path to be volatile here, if we would assume Path to be
> > > truly immutable. volatility here required only for ensuring safe
> > > publishing.
> > >
> > > 2012/8/13 David Holmes <davidcholmes at aapt.net.au>:
> > >
> > > Ruslan Cheremin writes:>
> > >
> > > But is there a way to define "safe for data race publishing"? I as
> > > far, as I remember, "immutable and thread-safe" is standard mantra in
> > > JDK javadocs for totally safe objects. j.l.String has same mantra --
> > > and it is safe for any way of publishing. Does you mean, I should
> > > explicitly add "safe even for publishing via data race" in docs? But I
> > > can't remember any such phrase in JDK docs.
> > >
> > > I don't recall anything in the JDK docs that mention being
> > >
> > > "totally safe"
> > >
> > > regardless of publication mechanism. Some classes, eg String,
> have been
> > > defined such that they do have that property (for security
> reasons). In
> > > general neither "thread-safe" nor "immutable" imply
> > > safe-for-unsynchronized-publication.
> > >
> > > Java Concurrency In Practice (jcip.net) does define
> additional potential
> > > annotations, where @Immutable would indeed capture the requirement of
> > > safe-for-unsynchronized-publication.
> > >
> > > David
> > > -----
> > >
> > > 2012/8/13 David Holmes <davidcholmes at aapt.net.au>:
> > >
> > > Ruslan Cheremin writes:
> > >
> > > Well, Path javadoc explicitly says "immutable and safe for
> > > multithreaded use". Although it is not strictly defined in java what
> > > exactly means "safe for multithreaded use" -- does it mean safe for
> > > publishing via data race, among others? -- I suppose, it
> > >
> > > should be. Am
> > >
> > > I wrong here?
> > >
> > > "safe for multi-threaded use" does not generally imply that it
> > >
> > > is safe to
> > >
> > > publish instances without synchronization of some form.
> > >
> > > David
> > > -----
> > >
> > > From other side, File.toPath javadoc explicitly says what "returned
> > > instance must be the same for every invocation", so sync block is
> > > required here for mutual exclusion on initialization phase. Without
> > > this requirement it is also safe to live without sync block, afaik.
> > >
> > > 2012/8/13 David Holmes <davidcholmes at aapt.net.au>:
> > >
> > > Ruslan Cheremin writes:
> > >
> > > First of all, Path is immutable, so DCL is safe here even without
> > > volatile. Volatile here is not required from my point of view.
> > >
> > > Without the volatile the Path implementation (Path is an
> > >
> > > interface) must be
> > >
> > > such that an instance of Path can be safely published without
> > >
> > > any additional
> > >
> > > forms of synchronization. Immutability does not in itself
> > >
> > > ensure that. You
> > >
> > > would have to examine the actual implementation class.
> > >
> > > David Holmes
> > > ------------
> > >
> > > 2012/8/12 Dmitry Vyazelenko <vyazelenko at yahoo.com>:
> > >
> > > Hi Richard,
> > >
> > > The variable "filePath" is volatile, so the double-checked
> > >
> > > locking is correct in this case. It would have been a bug
> > >
> > > prior to Java 5.
> > >
> > > Best regards,
> > >
> > > Dmitry Vyazelenko
> > >
> > > On Aug 12, 2012, at 21:35 , Richard Warburton
> > >
> > > <richard.warburton at gmail.com> wrote:
> > >
> > > Hello,
> > >
> > > The current implementation of java.io.File::toPath [0]
> > >
> > > appears to be
> > >
> > > using the double checked locking pattern:
> > >
> > >     public Path toPath() {
> > >         Path result = filePath;
> > >         if (result == null) {
> > >             synchronized (this) {
> > >                 result = filePath;
> > >                 if (result == null) {
> > >                     result =
> > >
> > > FileSystems.getDefault().getPath(path);
> > >
> > >                     filePath = result;
> > >                 }
> > >             }
> > >         }
> > >         return result;
> > >     }
> > >
> > > I was going to report the bug, but I'm a little
> > >
> > > uncertain of the
> > >
> > > interaction between the local variable 'result' and DCL
> > >
> > > since I've
> > >
> > > previously only seen the checking condition on the
> > >
> > > shared field
> > >
> > > itself.  Can someone here either confirm that its a bug or
> > >
> > > explain how
> > >
> > > the 'result' variable is fixing things?
> > >
> > > regards,
> > >
> > >  Richard
> > >
> > > [0] See the end of
> > >
> > > hg.openjdk.java.net/jdk8/jdk8/jdk/file/da8649489aff/src/share/clas
> > >
> > > ses/java/io/File.java
> > >
> > > _______________________________________________
> > > Concurrency-interest mailing list
> > > Concurrency-interest at cs.oswego.edu
> > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > >
> > > _______________________________________________
> > > Concurrency-interest mailing list
> > > Concurrency-interest at cs.oswego.edu
> > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > >
> > > _______________________________________________
> > > Concurrency-interest mailing list
> > > Concurrency-interest at cs.oswego.edu
> > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > >
> > > _______________________________________________
> > > Concurrency-interest mailing list
> > > Concurrency-interest at cs.oswego.edu
> > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > >
> > >
> > >
> > > _______________________________________________
> > > Concurrency-interest mailing list
> > > Concurrency-interest at cs.oswego.edu
> > > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> > >
> >
>
> _______________________________________________
> 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