ListBuffer
is used as List.newBuilder
and its toList
serves as the implementation for builder’s result()
. Before returning the head element of the underlying list to the application, it calls releaseFence()
. This means that whatever val
or var
the returned List
is assigned to, lets call it x
, the assignment will happen after all mutations performed via the builder/buffer. But it’s not good enough, is it? Because any thread reading (‘loading’) x
and x.tail
can have the load of x.tail
reordered before the load of x
. Unless JVM implements the dereferencing ordering (any value read through a pointer is at least as new as the pointer value), and I don’t think it does, it means that the load of x.tail
can actually happen in real time before the call to releaseFence()
and thus potentially read stale data.
Now, I admit I don’t feel entirely comfortable with memory fences, but this seems like the most basic use case and goes against what all primers on fences seem to show. What am I missing?