Je lisais l'article Singleton sur Wikipedia et je suis tombé sur cet exemple:
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;
}
}
Bien que j'aime vraiment la façon dont ce Singleton se comporte, je ne vois pas comment l'adapter pour incorporer des arguments au constructeur. Quelle est la meilleure façon de procéder en Java? Dois-je faire quelque chose comme ça?
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;
}
}
Merci!
Edit: Je pense que j'ai commencé une tempête de controverse avec mon désir d'utiliser Singleton. Laissez-moi vous expliquer ma motivation et j'espère que quelqu'un pourra suggérer une meilleure idée. J'utilise un cadre de calcul en grille pour exécuter des tâches en parallèle. En général, j'ai quelque chose comme ça:
// 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).
}
}
Ce qui se passe, c'est que même si je transmets simplement une référence à mes données à toutes les tâches, lorsque les tâches sont sérialisées, les données sont copiées encore et encore. Ce que je veux faire, c'est partager l'objet entre toutes les tâches. Naturellement, je pourrais modifier la classe comme ceci:
// 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).
}
}
Comme vous pouvez le voir, même ici, j'ai le problème que le passage d'un chemin de fichier différent ne signifie rien après le premier. C'est pourquoi j'aime l'idée d'un magasin qui a été affichée dans les réponses. Quoi qu'il en soit, plutôt que d'inclure la logique de chargement du fichier dans la méthode d'exécution, je voulais résumer cette logique dans une classe Singleton. Je ne donnerai pas encore un autre exemple, mais j'espère que vous comprenez l'idée. S'il vous plaît laissez-moi entendre vos idées pour une manière plus élégante d'accomplir ce que j'essaie de faire. Merci encore!