Is SharedSecrets thread-safe?
Brett Okken
brett.okken.os at gmail.com
Tue Dec 29 21:33:04 UTC 2020
What guarantees that if the first read does not see null, the second read
will not see null?
Sections 4.2 and 4.4 of Aleksey’s “Close Encounters of the JMM Kind” seem
to show that such scenario is possible in face of concurrent setting of
non-volatile variable.
https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-hb-actual
https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-unobserved-sync
On Tue, Dec 29, 2020 at 3:17 PM Johannes Kuhn <info at j-kuhn.de> wrote:
> It's a bit more complicated - after all we are talking about the memory
> model and class loading.
>
> There are some shared secrets that can be loaded later (e.g. AWT), when
> Threads are there.
>
> The field is only set in one single place inside the JDK, so we are
> talking about 3 scenarios:
>
> * The class is not yet loaded - the field is null, call
> ensureClassInitialized - which executes the class initializer on the
> current thread. A subsequent read of the field must be visible - as
> actions performed in the thread appear to be sequential for that thread.
>
> * The class has been successfully loaded, everything relating to that is
> visible.
>
> * The class is currently initialized by an other thread:
> * The first load of the field yields null - ensureClassInitialized
> blocks until the class has been loaded.
> * The first load yields something different than null.
> The question now is: can the second load yield the previous value?
> That is: can a field revert to it's original value?
> Other fields may not be visible yet (except if they have been frozen).
> So the big question is: can the second read return null after the
> first has found it to be a non-null value?
>
> After reading the "Double checked locking is broken"[1] declaration
> again - it says that it does work for primitive values that can't be
> teared. The problem seems to be that the field of the referenced objects
> are not yet constructed.
>
> The good news: the implementations of the shared secrets don't have
> fields. The better news: reference assignment also can't be teared.
>
> - Johannes
>
> [1]:
> https://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
>
> On 29-Dec-20 18:53, Hans Boehm wrote:
> >
> >
> > On Tue, Dec 29, 2020 at 5:56 AM Johannes Kuhn <info at j-kuhn.de
> > <mailto:info at j-kuhn.de>> wrote:
> > >
> > > Depends on what `initialize()` is.
> > >
> > > If it (at least) reads a volatile field, then the compiler can't
> reorder
> > > the second read before the first.
> > >
> > > - Johannes
> > I disagree with this claim. I have no idea whether concurrency is
> > possible here, so it may not matter. See below.
> >
> > >
> > > On 29-Dec-20 14:42,
> > some-java-user-99206970363698485155 at vodafonemail.de
> > <mailto:some-java-user-99206970363698485155 at vodafonemail.de>
> > > wrote:
> > > > Hello,
> > > > the class `jdk.internal.access.SharedSecrets` provides getter
> > methods which all look similar to this:
> > > > ```
> > > > if (static_field == null) {
> > > > initialize();
> > > > }
> > > > return static_field;
> > > > ```
> >
> > If static_field is not volatile, and set concurrently, then the first
> > read of static_field may return non-null and the second null, without
> > initialize() even being executed. The Java memory model does not prevent
> > reordering of non-volatile reads from the same field (for good reason).
> >
> > Even if initialize() is executed and performs a volatile read, this
> > reasoning doesn't hold. The initial static_field read may be delayed
> > past the volatile read inside the conditional and hence, at least
> > theoretically, past the second read. Control dependencies don't order
> > reads, either in Java, or in modern weakly-ordered architectures with
> > branch prediction. This doesn't matter if initialize() sets static_field.
> >
> > This all assumes that having two threads call initialize() is OK.
> >
> > Java code with data races is extremely tricky and rarely correct.
> >
> > Hans
>
More information about the core-libs-dev
mailing list