[concurrency-interest] Double Checked Locking in OpenJDK

Ruslan Cheremin cheremin at gmail.com
Mon Aug 13 16:20:13 EDT 2012


Yes, and it is my point -- it's confusing to say "immutable" (which
form of?), confusing to say "thread safe" (in which multithreaded use
case it is safe?) and even more confusing to say both "immutable and
thread-safe" -- because actually there is (==I know) only two ways to
reach thread-safe immutability in java: "all fields final", or "all
methods sync-ed, including constructors" -- and the second one is very
rare.

For me "immutable and thread safe" seems to be equivalent to
"thread-safe immutable", which, in turn, implies safety for data race
publication. How can I claim object as "thread safe immutable", if I
can see in several states in multithreaded env.?


2012/8/13 Yuval Shavit <yshavit at akiban.com>:
> This class is immutable but not thread-safe absent safe publication:
>
> public class MyImmutable {
>     private long val; // not marked final or volatile
>     public MyImmutable(long val) {
>         this.val = val;
>     }
>
>     public int getValue() {
>         return val;
>     }
> }
>
> In the absence of safe publication, a thread is allowed to see:
>
>     - val's default value (0)
>     - the value passed to the constructor
>     - a word tear in which val contains only the high or low word from the
> value passed to the constructor
>
>
> On Mon, Aug 13, 2012 at 3:39 PM, Ruslan Cheremin <cheremin at gmail.com> wrote:
>>
>> 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'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
>
>


More information about the Concurrency-interest mailing list