[concurrency-interest] Thread safety of WeakReference .get() method?

Aleksey Shipilev aleksey.shipilev at oracle.com
Wed Aug 8 10:11:37 EDT 2012

I had looked into disassembly and confirmed C2 had hoisted $referent and
reduced the readerThread loop to the infinite unconditional version.
>From the JMM standpoint, that is a correct optimization.

The genuine trouble seems to be the fact we are dealing with GC. If this
case was between two Java threads, one setting the value, and second one
is waiting in busy-loop, I would say it is a programming error not to
make the field in question "volatile".

In References, it is a bit tricker, now the "other" thread is GC. Even
if we say $referent is volatile, it does not immediately force native GC
thread to issue the barrier there. In fact, if you think about it, you
are updating it either during the STW pause, or through the appropriate
read-write barriers in concurrent phases; as if GC is already
maintaining the proper visibility for its own updates.

Hence, the compiler should probably handle the fields which are normally
updated by the GC in a specific way, e.g. prevent hoisting. Marking
referent as volatile brings that effect into life, but at the cost of
volatile write for the initial value (we had some optimization in mind
to handle that, but this is by no means a quick solution).


On 08/08/2012 05:22 PM, Vitaly Davidovich wrote:
> Adding the list in case someone has further insight.
> Sent from my phone
> On Aug 8, 2012 9:20 AM, "Vitaly Davidovich" <vitalyd at gmail.com
> <mailto:vitalyd at gmail.com>> wrote:
>     I should mention though that if you loop on WR.get(), as
>     demonstrated by Heinz, you can fall victim to compiler optimization
>     where the referent field is enregistered.  Almost seems like a bug,
>     but I'm guessing this is an unusual use case.
>     Sent from my phone
>     On Aug 8, 2012 9:14 AM, "Vitaly Davidovich" <vitalyd at gmail.com
>     <mailto:vitalyd at gmail.com>> wrote:
>         As Aleksey mentioned, one can assume that the interaction
>         between java and gc threads already has sufficient barriers to
>         make it work.  Otherwise, WeakReference would not work at all
>         even in single java thread case since GC runs on its own VM
>         threads.  Or did I miss your point?
>         Sent from my phone
>         On Aug 8, 2012 9:10 AM, "Raph Frank" <raphfrk at gmail.com
>         <mailto:raphfrk at gmail.com>> wrote:
>             On Wed, Aug 8, 2012 at 2:00 PM, Vitaly Davidovich
>             <vitalyd at gmail.com <mailto:vitalyd at gmail.com>> wrote:
>             > You will need to treat WeakReference as any other
>             non-threadsafe class and
>             > provide the necessary happens-before edges if you want to
>             share the instance
>             > amongst java threads.
>             The issue here is the sync between the garbage collection
>             thread(s)
>             and the reference.
>             The WeakReference is created in the constructor of another
>             object and
>             set to a final field.
>             It sounds like setting the last reference to null from one
>             thread and
>             using .get() from another can cause a problem.
> _______________________________________________
> 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