ich die Singleton Artikel auf Wikipedia zu lesen und ich kam in diesem Beispiel:Singleton mit Argumenten in Java
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;
}
}
Während ich die Art, wie das wirklich Singleton verhält, kann ich nicht sehen, wie es zur Anpassung an Integriere Argumente in den Konstruktor. 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!
Edit: Ich glaube, ich habe einen Sturm der Kontroverse mit meinem Wunsch, Singleton zu verwenden begonnen. 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 wie diese:
// 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).
}
}
Was ist passiert, dass, obwohl ich nur einen Verweis auf meine Daten an alle Aufgaben übergibt, wenn die Aufgaben serialisiert werden, werden die Daten kopiert und über. Ich möchte das Objekt unter allen Aufgaben teilen. Natürlich könnte ich die Klasse ändern, wie so:
// 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, auch hier hat ich das Problem, dass ein anderen Dateipfad vorbei bedeutet nichts, nachdem die erste übergeben wird. Deshalb mag ich die Idee für einen Speicher, der in den Antworten bekannt gegeben wurde. Jedenfalls wollte ich diese Logik in eine Singleton-Klasse abstrahieren, anstatt die Logik zum Laden der Datei in die run-Methode einzufügen. Ich werde kein weiteres Beispiel geben, 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!
Das Fabrikmuster ist, was Sie wollen. Im Idealfall sollten Grid-Aufgaben völlig unabhängig von anderen Dingen sein und alle Daten erhalten, die sie zur Ausführung und Rückgabe ihrer Ergebnisse benötigen. Dies ist jedoch nicht immer die praktikabelste Lösung, daher ist die Serialisierung der Daten in eine Datei keine schlechte Idee. Ich denke, das ganze Singleton-Ding ist ein bisschen ein Red-Hering; Du willst kein Singleton. –
Es ist bedauerlich, dass Sie den Begriff Singleton verwendet haben, der mit einem solchen Gepäck kommt. Der richtige Ausdruck für dieses Muster ist eigentlich Interning. Interning ist eine Methode, um sicherzustellen, dass abstrakte Werte nur durch eine Instanz dargestellt werden. String Interning ist die gebräuchlichste Verwendung: en.wikipedia.org/wiki/String_intern_pool. – notnoop
Vielleicht möchten Sie sich Terracotta anschauen.Es verwaltet die Objektidentität im gesamten Cluster. Wenn Sie einen Verweis auf Daten senden, die sich bereits im Cluster befinden, wird er nicht erneut serialisiert. –