/ / Java im Singleton-Muster synchronisieren - Java, Synchronisation, Singleton

Java-Synchronisation im Singleton-Muster - Java, Synchronisation, Singleton

Muss das Synchronize-Schlüsselwort auf jede Methode einer Klasse angewendet werden, die das Singleton-Muster wie folgt implementiert?

public class Singleton {

private Singleton(){}

public synchronized static Singleton getInstance()
{
if(instance == null)
instance = new Singleton ();

return instance;
}

public void DoA(){
}
}

Da Singletons kein Publikum aussetzenKonstruktor und die Methode getInstance () wird synchronisiert. Die Methode DoA und andere öffentliche Methoden, die von der Singleton-Klasse verfügbar gemacht werden, müssen nicht synchronisiert werden.

Ist diese Argumentation richtig?

Antworten:

17 für die Antwort № 1

Es ist genau wie jede andere Klasse. Es kann oder muss nicht weiter synchronisiert werden.

Betrachten Sie das folgende Beispiel:

public class Singleton {

private Singleton() {}

public synchronized static Singleton getInstance() { ... }

private int counter = 0;

public void addToCounter(int val) {
counter += val;
}
}

Wenn die Klasse aus mehreren Threads verwendet werden soll, addToCounter() hat eine Wettlaufbedingung. Eine Möglichkeit, das zu beheben, besteht darin, etwas zu machen addToCounter() synchronisiert:

  public synchronized void addToCounter(int val) {
count += val;
}

Es gibt andere Möglichkeiten, die Wettlaufsituation zu beheben, zum Beispiel mit AtomicInteger:

  private final AtomicInteger counter = new AtomicInteger(0);

public void addToCounter(int val) {
counter.addAndGet(val);
}

Hier haben wir den Race Condition ohne Verwendung festgelegt synchronized.


9 für die Antwort № 2

Nun, der Zweck der Singleton-Klasse ist, dass es höchstens eine Instanz davon gibt und dass alle Threads auf dasselbe Objekt zugreifen können.

Wenn du das nicht synchronisieren würdest getInstance Methode könnte folgendes passieren

Thread1 tritt ein getInstance()

Thread2 tritt ein getInstance()

Thread1 wertet aus instance == null zu true

Thread2 wertet aus instance == null zu true

Thread1 weist zu instance und kehrt zurück

Thread2 Revergibt instance = new Singleton() und kehrt zurück.

Nun haben die Threads beide eine Unterscheidungsinstanz der Singleton-Klasse, was durch dieses Muster verhindert werden sollte.

Durch das Synchronisieren wird verhindert, dass beide Threads gleichzeitig auf denselben Codeblock zugreifen können. Daher wird eine Synchronisierung in einer Multithread-Umgebung benötigt, wenn Sie Singleton-Klassen instanziieren.

Nun nehmen wir an, dass mehrere Threads versuchen werdenUm gleichzeitig auf die Singletons-Methoden zugreifen zu können, ist möglicherweise auch bei diesen Methoden eine Synchronisierung erforderlich. Besonders wenn sie Daten ändern, anstatt nur zu lesen, ist dies wahr.


1 für die Antwort № 3

Die richtige (Beste tatsächlich) Art, Singleton zu verwenden

private static singleton getInstance() {
if (minstance == null) {
synchronized (singleton.class) {
if (minstance == null) {
minstance = new singleton();
}
}
}
return minstance;
}

1 für die Antwort № 4

Lazy Initialization und Thread Safe Lösung:

public class Singleton {

public static class SingletonHolder {
public static final Singleton HOLDER_INSTANCE = new Singleton();
}

public static Singleton getInstance() {
return SingletonHolder.HOLDER_INSTANCE;
}
}