On 07/14/2017 03:40 PM, Claes Redestad wrote: > signature is already made volatile in this patch, deliberately to ensure that > for the private constructors we keep correctness: > > in these private constructors, the signature field is initialized in the > constructor (we can assert that it's non-null) to a value that would not > match getClassSignature(type), but since the field is volatile it will never > be observed as null by a call to getSignature() on an object created with > these constructors (unless I'm mistaken, and we *do* need an added > synchonization point here).
Thing is, "volatile" is not as strong as "final" for racy initializations: https://shipilev.net/blog/2016/close-encounters-of-jmm-kind/#wishful-volatiles-are-finals If that is not a concern -- e.g. if private constructor is never used to make shared OSFs -- then "volatile" is superfluous. If it is a concern, then "volatile" is not enough, and you have to keep "final". The hair-pull scenario under the race would be like this: OSF gets constructed with Ljava/lol/ConcurrencyIsHard, published, another thread calls getSignature() on it, eads null from $signature, regenerates it from Object $type, returns Ljava/lang/Object as signature. Something fails not expecting j/l/Object in signature, you go debug it, and see getSignature() returns Ljava/lol/ConcurrencyIsHard, as if nothing had happened. Thanks, -Aleksey