Ich habe den Singleton-Artikel auf Wikipedia gelesen und bin auf dieses Beispiel gestoßen:
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;
}
}
Obwohl mir das Verhalten dieses Singleton sehr gut gefällt, kann ich nicht sehen, wie ich es anpassen kann, um Argumente in den Konstruktor aufzunehmen. Was ist der bevorzugte Weg, dies in Java zu tun? Würde ich so etwas tun müssen?
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;
}
}
Vielen Dank!
Bearbeiten: Ich glaube, ich habe mit meinem Wunsch, Singleton zu verwenden, einen Sturm der Kontroversen ausgelöst. Lassen Sie mich meine Motivation erklären und hoffentlich kann jemand eine bessere Idee vorschlagen. Ich verwende ein Grid-Computing-Framework, um Aufgaben parallel auszuführen. Im Allgemeinen habe ich so etwas:
// 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).
}
}
Obwohl ich lediglich einen Verweis auf meine Daten an alle Aufgaben weitergebe, werden die Daten bei der Serialisierung der Aufgaben immer wieder kopiert. Ich möchte das Objekt auf alle Aufgaben verteilen. Natürlich könnte ich die Klasse so ändern:
// 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).
}
}
Wie Sie sehen können, habe ich auch hier das Problem, dass das Übergeben eines anderen Dateipfads nichts bedeutet, nachdem der erste übergeben wurde. Aus diesem Grund gefällt mir die Idee für ein Geschäft, das in den Antworten veröffentlicht wurde. Anstatt die Logik zum Laden der Datei in die Ausführungsmethode aufzunehmen, wollte ich diese Logik in eine Singleton-Klasse abstrahieren. Ich werde kein weiteres Beispiel nennen, aber ich hoffe, Sie haben die Idee. Bitte lassen Sie mich Ihre Ideen für einen eleganteren Weg hören, um das zu erreichen, was ich versuche. Danke nochmal!