Implementare un Singleton

Il singleton è un design pattern di tipo creazionale. La sua funzione è quella di garantire, all' interno di un ambiente software, un' unica istanza di una determinata classe. In java il meccanismo di implementazione per permettere questo tipo di comportamento è molto semplice. Infatti basta rendere il costruttore della classe con il modificatore di accesso private e delegare la creazione dell' istanza ad un metodo di tipo statico :
public class Singleton {

	private static Singleton istance=null; //riferimento all' istanza

	private Singleton() {}//costruttore

	public static Singleton getIstance() {
		if(istance==null)
			istance = new Singleton();
		return istance;
	}

	public void metodo() { ... }
	....
}
Come potete notare dal codice, nella classe mantenimo un riferimento all' istanza con un attributo di tipo static, che inizialmente è uguale a null. Non appena viene richiamato getIstance(), il metodo verifica se l' istanza è stata già creata, altrimenti ne crea una nuova.
...
Singleton sg1 = Singleton.getIstance(); //Crea l' stanza
sg1.metodo();
...
Singleton sg2 = Singleton.getIstance(); //Ritorna il riferimento
sg2.metodo();
...
//sg1 e sg2 puntanto allo stesso oggetto
In questo modo l' istanza viene create al primo tentativo di utilizzo e nelle successive chiamate viene restituito il riferimento alla classe istanziata. Questa soluzione non è adatta in ambienti multi-threading, in cui possono verificarsi chiamate concorrenti e quindi un eventuale incosistenza dei dati durante la creazione dell' istanza. Una possibile soluzione in questo caso è quello di sincronizzare il metodo getIstance() nel modo seguente :
public synchronized static Singleton getIstance() {
	if(istance==null)
		istance = new Singleton();
	return istance;
}
Questa implementazione risulta a sua volta inefficiente poichè genera ovheread, cioè ad ogni chiamata del metodo getIstance() il thread deve ottenere il lock. Vediamo allora un' altra implementazione ottimizzata, utilizzando il blocco synchronized solo nel caso in cui non è stata creata nessuna istanza :
public static Singleton getIstance() {
	if(istance==null)
		synchronized(Singleton.class) {
			if( instance == null )
				istance = new Singleton();
			}
	return istance;
}
Questa strategia viene definita double-checked locking. Esistono comunque altre modalità implementative per evitare l' overhead usando dei meccanismi di sincronizzazione implicita, ma questo riguarda casi di singleton strutturalmente molto complessi.
Altri link che potrebbero interessarti
  • Utilizzare un JButton in Java Swing
  • Utilizzare HTML in componenti Java Swing
  • Numeri casuali in java
  • Modalità Full Screen Exclusive in java
  • Leggere un file di testo in java
  • Le variabili atomiche in java
  • Le classi anonime
  • Java Regex
  • Java Database MySql
  • Java Cursor Mouse
  • Import Static Java
  • Implementare un KeyListener in java Swing
  • Implementare il System.out su una JTextArea
  • Il costrutto if in java
  • Il costrutto foreach in java
  • Il blocco static
  • Creare una ToolBar in Java Swing
  • Chiudere le applicazioni Java Swing
  • Bordo con titolo in Java Swing
  • Background Image per componenti Java Swing