Qual è il punto di doppio controllo di blocco?

-2

Ho letto l'articolo di Wikipedia sul blocco a doppio controllo e una cosa che non è chiara (almeno per me) è ciò che il modello raggiunge. Qual è la ragione per fare i due assegni qui sotto? Perché non avere un blocco triplo controllato? Non sarebbe ancora meglio?

if (mySingleton == null) { // 1st check
            lock (myLock) {
                if (mySingleton == null) { // 2nd (double) check
                    mySingleton = new MySingleton();
                }
            }
        }
    
posta Sachin Kainth 16.09.2013 - 12:38
fonte

2 risposte

12

La versione corretta senza blocco a doppio controllo è:

lock (myLock) {
    if (mySingleton == null) { // 2nd (double) check
        mySingleton = new MySingleton();
    }
}

Tuttavia ciò richiede l'operazione costosa di ottenere un lock ogni volta che si desidera ottenere il singleton, tuttavia il blocco è in realtà necessario solo una volta (durante la prima inizializzazione).

Quindi è stato introdotto il double check dove un thread controllerà mySingleton al di fuori del lock e se passa il primo check ( mySingleton non è null ) allora non è necessario preoccuparsi di acquisire il lock.

Il controllo interno rimane per evitare la condizione di competizione quando 2 thread raggiungono il blocco di blocco per inizializzare mySingleton , tuttavia ciò può causare una doppia inizializzazione se il controllo interno non è presente (2 thread vanno nel blocco di blocco attivo al momento ).

Aggiungere un terzo controllo è inutile, ci sono solo 2 stati reali qui: all'esterno della serratura e all'interno della serratura. Dove metteresti il terzo controllo?

    
risposta data 16.09.2013 - 12:50
fonte
-2

Vale la pena notare che in C # esiste un approccio thread-safe che evita la necessità di utilizzare il blocco per creare l'istanza Singleton.

class MyClass
{
    //  Static constructor - Can only by called once per application domain.
    static MyClass()
    {
        //  We must be the only thread.
        MyClass.Instance = new MyClass(); 
    }

    static public MyClass Instance { get; private set; }

    protected MyClass()
    {
        //  Class constructor.
    }
}
    
risposta data 16.09.2013 - 13:12
fonte

Leggi altre domande sui tag