/ / Java synchronizuje w trybie singleton - java, synchronization, singleton

Java synchronizuje w trybie singleton - java, synchronization, singleton

Czy słowo kluczowe synchronize należy zastosować do każdej metody klasy implementującej wzorzec singleton?

public class Singleton {

private Singleton(){}

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

return instance;
}

public void DoA(){
}
}

Ponieważ Singletons nie ujawnia publicznościkonstruktor i metoda getInstance () jest zsynchronizowana, nie trzeba synchronizować metody DoA i żadnych innych metod publicznych ujawnianych przez klasę Singleton.

Czy to rozumowanie jest poprawne?

Odpowiedzi:

17 dla odpowiedzi nr 1

To tak, jak każda inna klasa. Może wymagać dalszej synchronizacji lub nie.

Rozważmy następujący przykład:

public class Singleton {

private Singleton() {}

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

private int counter = 0;

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

Jeśli klasa ma być używana z wielu wątków, addToCounter() ma stan wyścigu. Jednym ze sposobów naprawienia tego jest robienie addToCounter() zsynchronizowany

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

Są inne sposoby na naprawienie wyścigu, na przykład za pomocą AtomicInteger:

  private final AtomicInteger counter = new AtomicInteger(0);

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

Tutaj naprawiliśmy warunki wyścigu bez użycia synchronized.


9 dla odpowiedzi nr 2

Celem klasy Singleton jest to, że istnieje co najwyżej jedna jej instancja i że wszystkie wątki mają dostęp do tego samego obiektu.

Jeśli nie zsynchronizowałeś getInstance metoda następujące może się zdarzyć

Wątek1 wchodzi getInstance()

Wątek 2 wchodzi getInstance()

Wątek1 ocenia instance == null do true

Wątek2 ocenia instance == null do true

Wątek1 przypisuje instance i zwraca

Wątek2 reprzydziela instance = new Singleton() i zwraca.

Teraz oba wątki mają instancję różniczkową klasy Singleton, co powinno temu zapobiec.

Synchronizacja zapobiega temu, aby oba wątki miały dostęp do tego samego bloku kodu w tym samym czasie. Tak więc synchronizacja jest potrzebna w środowisku wielowątkowym podczas tworzenia klas singletowych.

Teraz przy założeniu, że wiele wątków spróbujeaby uzyskać dostęp do metod Singleton w tym samym czasie synchronizacja może być również konieczna w przypadku tych metod. Zwłaszcza jeśli zmieniają dane zamiast tylko je czytać, to prawda.


1 dla odpowiedzi nr 3

Prawidłowy (najlepszy w rzeczywistości) sposób korzystania z Singleton

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

1 dla odpowiedzi nr 4

Leniwe inicjowanie i bezpieczne rozwiązanie wątku:

public class Singleton {

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

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