Skip to content

Gendarme.Rules.Concurrency.DoubleCheckLockingRule(2.10)

Sebastien Pouliot edited this page Jan 22, 2011 · 2 revisions

DoubleCheckLockingRule

Assembly: Gendarme.Rules.Concurrency
Version: 2.10

Description

This rule is used to check for the double-check pattern, often used when implementing the singleton pattern (1), and warns of potential incorrect usage. The original CLR (1.x) could not guarantee that a double-check would work correctly in multithreaded applications. However the technique does work on the x86 architecture, the most common architecture, so the problem is seldom seen (e.g. IA64). The CLR 2 and later introduce a strong memory model (2) where a double check for a lock is correct (as long as you assign to a volatile variable). This rule won't report a defect for assemblies targetting the 2.0 (and later) runtime.

Examples

Bad example:

public class Singleton {
    private static Singleton instance;
    private static object syncRoot = new object ();
    public static Singleton Instance {
        get {
            if (instance == null) {
                lock (syncRoot) {
                    if (instance == null) {
                        instance = new Singleton ();
                    }
                }
            }
            return instance;
        }
    }
}

Good example (for 1.x code avoid using double check):

public class Singleton {
    private static Singleton instance;
    private static object syncRoot = new object ();
    public static Singleton Instance {
        get {
            // do not check instance before the lock
            // this will work on all CLRs but will affect
            // performance since the lock is always acquired
            lock (syncRoot) {
                if (instance == null) {
                    instance = new Singleton ();
                }
            }
            return instance;
        }
    }
}

Good example (for 2.x and later):

public class Singleton {
    // by using 'volatile' the double check will work under CLR 2.x
    private static volatile Singleton instance;
    private static object syncRoot = new object ();
    public static Singleton Instance {
        get {
            if (instance == null) {
                lock (syncRoot) {
                    if (instance == null) {
                        instance = new Singleton ();
                    }
                }
            }
            return instance;
        }
    }
}

Clone this wiki locally