Stavo leggendo l'articolo di Singleton su Wikipedia e mi sono imbattuto in questo esempio:
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
Anche se mi piace molto il modo in cui questo Singleton si comporta, non riesco a vedere come adattarlo per incorporare argomenti nel costruttore. Qual è il modo preferito per farlo in Java? Dovrei fare qualcosa del genere?
public class Singleton
{
private static Singleton singleton = null;
private final int x;
private Singleton(int x) {
this.x = x;
}
public synchronized static Singleton getInstance(int x) {
if(singleton == null) singleton = new Singleton(x);
return singleton;
}
}
Grazie!
Modifica: Penso di aver iniziato una tempesta di polemiche con il mio desiderio di usare Singleton. Lasciami spiegare la mia motivazione e spero che qualcuno possa suggerire un'idea migliore. Sto usando un framework di grid computing per eseguire compiti in parallelo. In generale, ho qualcosa del genere:
// AbstractTask implements Serializable
public class Task extends AbstractTask
{
private final ReferenceToReallyBigObject object;
public Task(ReferenceToReallyBigObject object)
{
this.object = object;
}
public void run()
{
// Do some stuff with the object (which is immutable).
}
}
Quello che succede è che anche se ho semplicemente passato un riferimento ai miei dati a tutte le attività, quando le attività sono serializzate, i dati vengono copiati più e più volte. Quello che voglio fare è condividere l'oggetto tra tutte le attività. Naturalmente, potrei modificare la classe in questo modo:
// AbstractTask implements Serializable
public class Task extends AbstractTask
{
private static ReferenceToReallyBigObject object = null;
private final String filePath;
public Task(String filePath)
{
this.filePath = filePath;
}
public void run()
{
synchronized(this)
{
if(object == null)
{
ObjectReader reader = new ObjectReader(filePath);
object = reader.read();
}
}
// Do some stuff with the object (which is immutable).
}
}
Come puoi vedere, anche qui ho il problema che passare un percorso di file diverso non significa nulla dopo che il primo è passato. Ecco perché mi piace l'idea di un negozio che è stato pubblicato nelle risposte. Comunque, piuttosto che includere la logica per caricare il file nel metodo run, volevo astrarre questa logica in una classe Singleton. Non fornirò ancora un altro esempio, ma spero che tu abbia avuto l'idea. Per favore, fammi ascoltare le tue idee per un modo più elegante di realizzare ciò che sto cercando di fare. Grazie ancora!