Newsgroup: it.comp.java
Titolo: singleton thread safe

Ho trovato alcune implementazioni di un singleton "thread safe" in questo
modo:
class pippo {
private static pippo instance = null;
private pippo() {}
static pippo getInstance() {
if(instance == null) {
synchronized(pippo.class)
   instance = new pippo();
}
return instance;
}
....
con la tecnica del double checked locking per evitare che 2 thread facciano
contemporaneamente la richiesta getInstance quando l'instanza non è ancora
stata creata.
Ma non bastava questo??:
class pippo {
private static pippo instance = new pippo();
private pippo() {}
public static pippo getInstance() {return instance;}
}
}
instance viene creata una volta sola perchè è static, e getInstance non va
alcuna modifica, quindi non dovrebbero esserci problemi di condivisione.
E allora pechè non si utilizza la seconda?
}

 E allora pechè non si utilizza la seconda?
Sì può bastare la seconda soluzione che hai dato.
Essa è corretta e garantisce che un unica istanza di pippo
sia creata a run-time.
Certe volte conviene però la soluzione precedente (corretta!)
quando si voglia postporre il momento della creazione di pippo.
Con la seconda soluzione pippo viebe creato non appena
(per qualsivoglia ragione) la JVM debba caricare la classe pippo
(per esempio perché nel programma si utilizza un metodo statico
di pippo) ma questo momento potrebbe non essere quello corretto
(in termini di specifiche del programma) per la creazione
di pippo che si vuole invece ritardare alla prima invocazione di
getInstance().
Ad esempio il seguente programma:
   class Singleton {
     private static Singleton instance = new Singleton();
     private Singleton() {System.out.println("Singleton");}
     public static Singleton getInstance() {return instance;}
     public static void main(String args[]) {
       System.out.println("Prima");
       getInstance();
       System.out.println("Dopo");
     }
   }
stampa:
   Singleton
   Prima
   Dopo
mentre il seguente programma:
   class Singleton {
     private static Singleton instance;
     private Singleton() {System.out.println("Singleton");}
     static Singleton getInstance() {
       if(instance == null) {
         synchronized(Singleton.class) {
           if(instance == null)
             instance = new Singleton();
         }
       }
       return instance;
     }
     public static void main(String args[]) {
       System.out.println("Prima");
       getInstance();
       System.out.println("Dopo");
     }
   }
stampa:
   Prima
   Singleton
   Dopo
che è quello che magari volevo proprio ottenere (perchè magari
l'istanza di Singleton deve essere creata solo dopo che certe altre
operazioni sono state fatte).
- Dario

 getInstance().
Ok grazie.
Nel mio caso non fa nessunissima differenza! quindi mi tengo la seconda
versione.

     }
Mi correggo.
Ovviamente neanche la precedente è corretta (a voi scoprire il perché!).
Questa lo è:
     static synchronized pippo getInstance() {
       if(instance == null)
         instance = new pippo();
       return instance;
     }
- Dario

 E allora pechŠ non si utilizza la seconda?
Per fare lazy initialization. Concordo che il 90% delle volte serve solo al 
programmatore per divertirsi.