[concurrency-interest] Double Checked Locking in OpenJDK

Stanimir Simeonoff stanimir at riflexo.com
Tue Aug 14 17:05:56 EDT 2012


I am not sure how deep EA can go, struct saves the object header and
indirection. EA can't help when the object escapes for real. Actually I'd
not care about the cases where EA can be applied directly.
Structs are interesting when applied over DirectBuffers, though. The latter
is necessary to communicate to native code and stuff like OpenGL.

Stanimir

On Tue, Aug 14, 2012 at 11:47 PM, Ruslan Cheremin
<cherermin at gmail.com<cheremin at gmail.com>
> wrote:

> Although I frequently see the cases where structs would be useful for
> optimization purposes, I think it is generally bad idea to introduce
> them in java. It would be good idea 10 years ago, but now? I'm pretty
> sure it should (and can) be done on JIT level. Escape analyze is the
> first step.
>
> 2012/8/15 Vitaly Davidovich <vitalyd at gmail.com>:
> > Really need value types/structs in the jvm to lower the cost of such
> > abstractions (and numerous other ones too).  Is there even a remote
> chance
> > we'll see that in this lifetime? :)
> >
> > Sent from my phone
> >
> > On Aug 14, 2012 4:31 PM, "Stanimir Simeonoff" <stanimir at riflexo.com>
> wrote:
> >>
> >>
> >>
> >> On Tue, Aug 14, 2012 at 11:24 PM, Vitaly Davidovich <vitalyd at gmail.com>
> >> wrote:
> >>>
> >>> Your point about "const" reminded me that I agree with Joe Duffy on his
> >>> take [1] on the fact that annotating a field as volatile or final (he
> talks
> >>> about volatile, but the point can be extended to final) doesn't really
> >>> belong to the field; the type of order required is determined at the
> point
> >>> of access, not declaration.  I think c++11 got this part quite right.
> >>>
> >>> [1]
> http://www.bluebytesoftware.com/blog/2010/12/04/SayonaraVolatile.aspx
> >>
> >> Yeah, the one about the "bastardized" volatile :) Remember it clearly.
> >> However it's way too late to modify Java to accommodate for. Having only
> >> AtomicXXX built-in types, impl. via intrinsics would have been much
> better
> >> as code like
> >> volatile X x;
> >> if (x!=null && x.foo()) x.bar();
> >>
> >> would be significantly easier to spot during writing cycle for most of
> the
> >> people.
> >>
> >> Stanimir
> >>
> >>> Sent from my phone
> >>>
> >>> On Aug 14, 2012 4:12 PM, "Stanimir Simeonoff" <stanimir at riflexo.com>
> >>> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On Tue, Aug 14, 2012 at 10:58 PM, Zhong Yu <zhong.j.yu at gmail.com>
> wrote:
> >>>>>
> >>>>> On Tue, Aug 14, 2012 at 2:52 PM, Vitaly Davidovich <
> vitalyd at gmail.com>
> >>>>> wrote:
> >>>>> > Yes, presumably on some archs with very weak memory order it could
> >>>>> > cause
> >>>>> > some performance impact.  On TSO, it's just a compiler barrier
> >>>>> > preventing
> >>>>> > code motion that would publish the reference before constructor
> >>>>> > completes,
> >>>>> > but on those weak archs it could also mean a hardware fence.
>  Whether
> >>>>> > the
> >>>>> > tradeoff is worth it in general or not is debatable.  You can't
> have
> >>>>> > it both
> >>>>> > ways, I agree, but the jvm and JMM give you options and guidance on
> >>>>> > how to
> >>>>> > do the "right" thing.
> >>>>>
> >>>>> If I'm writing a Java library, containing a Point(x,y) class, which
> is
> >>>>> immutable (in the narrower sense), should I use final fields or not?
> >>>>> What's the "right" thing to do?
> >>>>>
> >>>> If you greatly care about performance and since Java doesn't have
> struct
> >>>> alikes (yet) and you are going to have tons of Point(s), just 2
> >>>> double[]/int[] to reduce the cache misses/indirections - i.e. that's
> another
> >>>> option how to organize your code.
> >>>> OTOH if you choose more OO aproach it's still up to you - you have an
> >>>> option to make it look "better" w/ final fields or forgo 'em
> potentionally
> >>>> saving store-store on PowerPC.
> >>>>
> >>>> That reminds me the keyword 'const' is unsed and potetially can be
> what
> >>>> "final" is for fields but w/o memory/compiler barriers.
> >>>>
> >>>> Stanimir
> >>>>>
> >>>>> >
> >>>>> > Sent from my phone
> >>>>> >
> >>>>> > On Aug 14, 2012 3:47 PM, "Zhong Yu" <zhong.j.yu at gmail.com> wrote:
> >>>>> >>
> >>>>> >> Are `final` fields a problem to compiler optimization?
> >>>>> >>
> >>>>> >> You can't have both ways.
> >>>>> >>
> >>>>> >> Either `final` field semantics is good and cheap, therefore it
> >>>>> >> should
> >>>>> >> be extended to all fields.
> >>>>> >>
> >>>>> >> Or there is some downsides with 'final' field semantics, so we
> >>>>> >> shouldn't encourage people to apply `final` whenever they can.
> Lets
> >>>>> >> hear those downsides.
> >>>>> >>
> >>>>> >> Zhong Yu
> >>>>> >>
> >>>>> >> On Tue, Aug 14, 2012 at 2:42 PM, Vitaly Davidovich
> >>>>> >> <vitalyd at gmail.com>
> >>>>> >> wrote:
> >>>>> >> > This is only an issue when publishing unsafely.  Allowing
> treating
> >>>>> >> > constructors as regular methods is a good thing as it gives the
> >>>>> >> > compiler
> >>>>> >> > a
> >>>>> >> > chance to optimize code, which everyone likes and benefits from.
> >>>>> >> >
> >>>>> >> > Sent from my phone
> >>>>> >> >
> >>>>> >> > On Aug 14, 2012 3:39 PM, "Zhong Yu" <zhong.j.yu at gmail.com>
> wrote:
> >>>>> >> >>
> >>>>> >> >> From a user's point of view, shouldn't constructors be special
> >>>>> >> >> though?
> >>>>> >> >> An object shouldn't be considered in existence until its
> >>>>> >> >> construction
> >>>>> >> >> is done; it is pathological that some outsider can observe a
> >>>>> >> >> partially
> >>>>> >> >> constructed object. Life is simpler if we can eliminate that
> >>>>> >> >> possibility (unless `this` is leaked inside constructor)
> >>>>> >> >>
> >>>>> >> >> Zhong Yu
> >>>>> >> >>
> >>>>> >> >> On Tue, Aug 14, 2012 at 1:58 PM, Nathan Reynolds
> >>>>> >> >> <nathan.reynolds at oracle.com> wrote:
> >>>>> >> >> > 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
> >>>>> _______________________________________________
> >>>>> 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
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120815/56763c17/attachment-0001.html>


More information about the Concurrency-interest mailing list