Singleton pattern: quando e come usarlo.

Traendo ispirazione su un post trovato per la rete, ho deciso di scrivere un piccolo, ma proprio piccolo post, sul pattern Singleton, molto usato durante le sessioni di programmazione per risolvere una certa classe di problemi comuni. Definiamo un singleton come:
una classe per cui esiste una sola istanza nell’applicazione, e per la quale viene fornito un’unico punto globale di accesso.
Vediamo un possibile modo di implementare il singleton:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class DevMeSingleton {
    /* class instance */
    private static DevMeSingleton instance;
    /* Costruttore privato della classe */
    private DevMeSingleton() {}
 
    /* Metodo che permette di ottenere l'istanza della classe */
    public static DevMeSingleton getInstance() {
        if (instance==null) {
            instance = new DevMeSingleton();
        }
        return instance;
    }
}

1. Semplice implementazione singleton pattern

L’implementazione di cui sopra, può causare problemi di performance nel contesto di un applicazione multithreading. E’ possibili che 2 thread ottengano in contemporanea 2 istanze della classe singleton, violando così un presupposto fondamentale della definizione. Per far sì che il comportamento non sia critico in un contesto del genere, si consideri l’utilizzo della tecnica: double-checked locking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DevMeSingleton {
        /* class instance */
        private volatile static DevMeSingleton instance;
 
        /* Costruttore privato della classe */
        private DevMeSingleton() {}
 
        /* Metodo che permette di ottenere l'istanza della classe */
        public static DevMeSingleton getInstance() {
            if (instance==null) {
                synchronized(DevMeSingleton.class) {
                    if (instance==null) {
                        instance = new DevMeSingleton();
                    }
                }
            }
        return instance;
    }
}

2. Tecnica double-checked locking

Questa tecnica purtroppo non funziona con la JVM 1.4 a causa della defizione della variabile volatile, la quale non era stata ancora implementata. Per ovviare a questo problema, vediamo l’implementazione successiva. 

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DevMeSingleton {
 
        /* class instance */
        private static DevMeSingleton instance = new DevMeSingleton();
 
        /* Costruttore privato della classe */
        private DevMeSingleton() {}
 
        /* Metodo che permette di ottenere l'istanza della classe */
        public static DevMeSingleton getInstance() {
            return instance;
        }
}

3. Creazione efficiente dell’istanza di una classe Singleton

L’implementazione di cui sopra, garantisce la creazione efficiente dell’istanza della classe singleton, piuttosto di una creazione cosiddetta lazy (pigra). Il singleton viene creato all’atto dell’invocazione della classe, in quel momento vengono istanziate tutte le varibili static, tra cui anche l’istanza del singleton. Spero che possa essere utile. A presto.

| | More

3 Comments

  • By Gas, February 20, 2009 @ 2:16 pm

    Ciao Mulp.. il singleton ormai lo abbiamo studiato !
    Quando ci parli (chesso’ ?) di code-generation ?
    A presto !
    -Gas-

  • By Glauco, June 17, 2011 @ 5:09 pm

    vorrei proporti una quarta soluzione, che permette di utilizzare comunque lazy initialization.
    La soluzione prevede di includere una classe contenitore, la quale tramite un attributo statico, fornisce il vero accesso al singleton solo al momento dell’effettivo utilizzo.
    Ecco il codice:

    public class Singleton {
    private Singleton() {}
    private static class Contenitore {
    private final static Singleton ISTANZA = new Singleton();
    }
    public static Singleton getInstance() {
    return Contenitore.ISTANZA;
    }
    }

  • By Gabriele, October 22, 2011 @ 9:34 am

    Vorrei proporre una 5a soluzione. La soluzione nasconde il codice del Singleton nel codice binario – non puoi sbagliare!

    import com.dp4j.*;

    @Singleton(lazy=true)
    public class DevMeSingleton {
    //codice unico di questa classe
    }

Other Links to this Post

RSS feed for comments on this post.

Leave a comment

WordPress Themes