I wonder why does Safe Local DCL (one volatile read when instance is present) seem slower than Safe DCL (2 volatile reads when instance is present) in Table 4 (x86, 8 threads test)?
Not sure, but their margins of error overlap so it could be just a blip. I wouldn't read too much into those numbers; my take away is I always preferred Safe DCL but Holder looks more performant and cleaner to write (at the cost of an inner class).
I wish Java had a one-true-way for one-time static initialization like dispatch_once() in Objective-C.
You are right: it would be great to have one good approach. By the way, holder solves the problem when you don't need to pass arguments to singleton instance. In other cases Safe DCL, Safe Local DCL or Synchronized CL will work.
I wish Java had a one-true-way for one-time static initialization like dispatch_once() in Objective-C.