Una clase estática con una carga de variables estáticas es un truco.
/**
* Grotty static semaphore
**/
public static class Ugly {
private static int count;
public synchronized static void increment(){
count++;
}
public synchronized static void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized static boolean isClear(){
return count==0;
}
}
Un singleton con una instancia real es mejor.
/**
* Grotty static semaphore
**/
public static class LessUgly {
private static LessUgly instance;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( instance==null){
instance = new LessUgly();
}
return instance;
}
public synchronized void increment(){
count++;
}
public synchronized void decrement(){
count--;
if( count<0 ) {
count=0;
}
}
public synchronized boolean isClear(){
return count==0;
}
}
El estado está SOLO en la instancia.
Por lo tanto, el singleton se puede modificar más tarde para hacer agrupaciones, instancias locales de subprocesos, etc. Y no es necesario cambiar nada del código ya escrito para obtener el beneficio.
public static class LessUgly {
private static Hashtable<String,LessUgly> session;
private static FIFO<LessUgly> freePool = new FIFO<LessUgly>();
private static final POOL_SIZE=5;
private int count;
private LessUgly(){
}
public static synchronized getInstance(){
if( session==null){
session = new Hashtable<String,LessUgly>(POOL_SIZE);
for( int i=0; i < POOL_SIZE; i++){
LessUgly instance = new LessUgly();
freePool.add( instance)
}
}
LessUgly instance = session.get( Session.getSessionID());
if( instance == null){
instance = freePool.read();
}
if( instance==null){
// TODO search sessions for expired ones. Return spares to the freePool.
//FIXME took too long to write example in blog editor.
}
return instance;
}
Es posible hacer algo similar con una clase estática, pero habrá una sobrecarga por llamada en el envío indirecto.
Puede obtener la instancia y pasarla a una función como argumento. Esto permite que el código se dirija al singleton "correcto". Sabemos que solo necesitará uno ... hasta que no lo necesite.
El gran beneficio es que los singleton con estado se pueden convertir en seguros para subprocesos, mientras que una clase estática no, a menos que la modifique para que sea un singleton secreto.