Estaba leyendo el artículo de Singleton en Wikipedia y me encontré con este ejemplo:
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;
}
}
Aunque realmente me gusta la forma en que se comporta este Singleton, no puedo ver cómo adaptarlo para incorporar argumentos al constructor. ¿Cuál es la forma preferida de hacer esto en Java? ¿Tendría que hacer algo como esto?
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;
}
}
¡Gracias!
Editar: Creo que he comenzado una tormenta de controversias con mi deseo de usar Singleton. Déjame explicarte mi motivación y espero que alguien pueda sugerir una mejor idea. Estoy usando un marco de computación grid para ejecutar tareas en paralelo. En general, tengo algo como esto:
// 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).
}
}
Lo que sucede es que a pesar de que simplemente paso una referencia a mis datos a todas las tareas, cuando las tareas se serializan, los datos se copian una y otra vez. Lo que quiero hacer es compartir el objeto entre todas las tareas. Naturalmente, podría modificar la clase así:
// 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).
}
}
Como puede ver, incluso aquí tengo el problema de que pasar una ruta de archivo diferente no significa nada después de que se pasa la primera. Es por eso que me gusta la idea de una tienda que se publicó en las respuestas. De todos modos, en lugar de incluir la lógica para cargar el archivo en el método de ejecución, quería abstraer esta lógica en una clase Singleton. No daré otro ejemplo más, pero espero que entiendan la idea. Permítame escuchar sus ideas para una forma más elegante de lograr lo que estoy tratando de hacer. ¡Gracias de nuevo!