Double-checked locking as an anti-pattern [duplica

2019-07-31 14:19发布

问题:

This question already has an answer here:

  • Java double checked locking 11 answers

There's a common belief and multiple sources (including wiki) that claim this idiom to be an anti-pattern.

  1. What are the arguments against using it in production code given the correct implementation is used (for example, using volatile)

  2. What are the appropriate alternatives for implementing lazy initialization in a multithreaded environment ? Locking the whole method may become a bottleneck and even while modern synchronization is relatively cheap, it's still much slower especially under contention. Static holder seems to be a language-specific and a bit ugly hack (at least for me). Atomics-based implementation seems not be so different from traditional DCL while allowing multiple calculations or requires more complicated code. For example, Scala is still using DCL for implementing the lazy values while proposed alternative seems to be much more complicated.

回答1:

Don't use double checked locking. Ever. It does not work. Don't try to find a hack to make it work, because it may not on a later JRE.

As far as I know, there is no other save way for lazy initialization than locking the whole object / synchronizing.

synchronized (lock) {
  // lookup

  // lazy init
}

For singletons the static holder (as @trashgod mentioned) is nice, but will not remain single if you have multiple classloaders.

If you require a lazy singleton in a multi-classloader environment, use the ServiceLoader.