Wiem, że użycie synchronize
słowa kluczowego przed metodą powoduje synchronizację z tym obiektem. Oznacza to, że zostaną zsynchronizowane 2 wątki z tym samym wystąpieniem obiektu.
Ponieważ jednak synchronizacja jest na poziomie obiektu, 2 wątki z różnymi instancjami obiektu nie zostaną zsynchronizowane. Jeśli w klasie Java mamy zmienną statyczną, która jest wywoływana przez metodę, chcielibyśmy, aby była zsynchronizowana między instancjami tej klasy. Te dwie instancje działają w 2 różnych wątkach.
Czy możemy osiągnąć synchronizację w następujący sposób?
public class Test
{
private static int count = 0;
private static final Object lock= new Object();
public synchronized void foo()
{
synchronized(lock)
{
count++;
}
}
}
Czy to prawda, że skoro zdefiniowaliśmy obiekt, lock
który jest statyczny i używamy słowa kluczowego synchronized
dla tej blokady, zmienna statyczna count
jest teraz zsynchronizowana między instancjami klasy Test
?
źródło
Odpowiedzi:
Istnieje kilka sposobów synchronizowania dostępu do zmiennej statycznej.
Użyj zsynchronizowanej metody statycznej. Spowoduje to synchronizację w obiekcie klasy.
Jawna synchronizacja w obiekcie klasy.
Zsynchronizuj z innym statycznym obiektem.
Metoda 3 jest najlepsza w wielu przypadkach, ponieważ obiekt blokady nie jest ujawniany poza klasą.
źródło
Test.class
i potencjalnie zepsuć Ci dzień. Ponadto inicjalizacja klasy przebiega z blokadą trzymanej klasy, więc jeśli masz szalone inicjatory klas, możesz wywołać ból głowy.volatile
nie pomaga,count++
ponieważ jest to sekwencja odczytu / modyfikacji / zapisu. Jak zauważono w innej odpowiedzi,java.util.concurrent.atomic.AtomicInteger
prawdopodobnie jest to właściwy wybór.Test.class
.this
byłaby blokadą dla zsynchronizowanych metod niestatycznychJeśli po prostu udostępniasz licznik, rozważ użycie AtomicInteger lub innej odpowiedniej klasy z pakietu java.util.concurrent.atomic:
źródło
Tak to jest prawda.
Jeśli utworzysz dwie instancje swojej klasy
Następnie t1.foo i t2.foo synchronizują się na tym samym obiekcie statycznym i blokują się wzajemnie.
źródło
Możesz zsynchronizować swój kod z klasą. To byłoby najprostsze.
Mam nadzieję, że ta odpowiedź okaże się przydatna.
źródło
Test.class
i wpływać na zachowanie. Dlategolock
preferowana może być synchronizacja .Możemy również użyć ReentrantLock, aby uzyskać synchronizację dla zmiennych statycznych.
źródło