Double-checked locking

A double- checked locking (English double -checked locking) is an anti- pattern, which occurs when a duplicate check is performed before a lockout occurs. This pattern is often used by inexperienced programmers who are aware of the problem of Lockings, but draw the wrong conclusions.

Double- checked locking in Java

Although with Java 5 under a new semantics of the keyword volatile a double checked locking can be implemented thread-safe, it is still considered anti-pattern, because it is too cumbersome and inefficient. In addition, the efficiency disadvantage of volatile is hardly less than of synchronized.

Example

The following example shows the problem in the getHelper () method, in which exactly for each Foo object is a helper object to be created lazy English:

Public class Foo {     private Helper helper = null;       public Helper getHelper () {       if ( helper == null ) / / first test synchronized (this ) {         if ( helper == null ) / / second test helper = new Helper ();       }       return helper;     }       / / ... } The Helper interface is used to work outside a Foo object on the helper object can. If we define here as helper is not as volatile, the double test is problematic because, for example, a Java JIT compiler can rearrange the assembly code so that the reference to the helper object is set before the constructor of the Helper object completely was run. In this case provides getHelper () an uninitialized object back.

Solution

From Java 5 volatile defined variables are visible only after complete execution of the constructor. Thus, if the helper variable is defined as volatile, the example above passes through correctly.

If - as in the implementation of a Singleton - is only one instance per class exist, there is an easy -to-implement solution: The attribute is declared as static and the creation of the object in a subclass ( here: nested class ) outsourced - the so called. initialization on demand holder idiom.

Public class Foo {     private static class HelperHolder {        public static Helper helper = new Helper ();     }       public Helper getHelper () {        return HelperHolder.helper;     }       / / ... Here, the static attribute of class HelperHolder is only instantiated when called by getHelper (), or " lazy", and the virtual machine ensures thread safety.

Double- checked locking in C #

Similar to Java exists the double checked locking in C #:

Class Singleton {    private Singleton ( ) {}    private static volatile Singleton instance;      public static Singleton Instance    {      get      {        if ( instance == null) { lock ( _lock ) {if (instance == null ) instance = new Singleton ();          }        }        return instance;      }    }      / / Auxiliary field for a safe thread synchronization private static object _lock = new object (); } While the synchronized keyword exists in C # does not, but it can be achieved via the MethodImpl attribute the same function. A separate lock object is not required.

Class Singleton {    private Singleton ( ) {}    private static volatile Singleton instance;      public static Singleton Instance    {      [ MethodImpl ( MethodImplOptions.Synchronized ) ] get      {        if ( instance == null )          instance = new Singleton ();        return instance;      }    } } References

  • Anti- Pattern
246667
de