Odpowiedzi:
Ponieważ metoda statyczna nie ma skojarzonego obiektu, czy synchronizowane słowo kluczowe będzie blokować klasę zamiast obiektu?
Tak. :)
this
czy blokada uzyskana w metodach instancji - napraw ją Oscar.
Aby dodać trochę szczegółów do (przyjemnie zwięzłej!) Odpowiedzi Oscara, odpowiednia sekcja specyfikacji języka Java to 8.4.3.6, `` Metody synchronizowane '' :
Zsynchronizowana metoda pozyskuje monitor ( §17.1 ) przed wykonaniem. W przypadku metody klasowej (statycznej) używany jest monitor skojarzony z obiektem Class dla klasy metody. W przypadku metody instancji używany jest monitor z nią powiązany (obiekt, dla którego metoda została wywołana).
Jedną kwestią, na którą trzeba uważać (kilku programistów zazwyczaj wpada w tę pułapkę) jest to, że nie ma połączenia między zsynchronizowanymi metodami statycznymi a zsynchronizowanymi metodami niestatycznymi, tj .:
class A {
static synchronized f() {...}
synchronized g() {...}
}
Główny:
A a = new A();
Wątek 1:
A.f();
Wątek 2:
a.g();
f () i g () nie są zsynchronizowane ze sobą i dlatego mogą być wykonywane całkowicie współbieżnie.
synchronized (MyClass.class) {...}
.
O ile nie zaimplementujesz g () w następujący sposób:
g() {
synchronized(getClass()) {
...
}
}
Uważam, że ten wzorzec jest przydatny również wtedy, gdy chcę zaimplementować wzajemne wykluczanie między różnymi instancjami obiektu (co jest potrzebne na przykład przy dostępie do zasobu zewnętrznego).
getClass()
zwraca typ środowiska uruchomieniowego ; jeśli podklasujesz klasę, to klasa nadrzędna i klasa potomna będą synchronizowane na różnych blokadach. synchronized(MyClass.class)
jest dobrym rozwiązaniem, jeśli chcesz upewnić się, że wszystkie instancje używają tej samej blokady.
Zajrzyj na stronę dokumentacji oracle na temat Intrinsic Locks and Synchronization
Możesz się zastanawiać, co się dzieje, gdy wywoływana jest statyczna metoda zsynchronizowana, ponieważ metoda statyczna jest skojarzona z klasą, a nie z obiektem. W takim przypadku wątek uzyskuje wewnętrzną blokadę dla obiektu Class skojarzonego z klasą . W ten sposób dostęp do pól statycznych klasy jest kontrolowany przez blokadę, która różni się od blokady dla dowolnej instancji klasy .
Metoda statyczna ma również powiązany obiekt. Należy do pliku Class.class w zestawie narzędzi JDK. Gdy plik .class ładuje się do pamięci RAM, klasa Class.class tworzy jego instancję o nazwie obiekt szablonu.
Np .: - gdy próbujesz stworzyć obiekt z istniejącej klasy klienta np
Customer c = new Customer();
Klasa Customer.class ładuje się do pamięci RAM. W tym momencie Class.class w zestawie narzędzi JDK tworzy obiekt o nazwie obiekt szablonu i ładuje tę klasę Customer.class do tego obiektu szablonu. Statyczne elementy składowe klasy Customer.class stają się atrybutami i metodami w tym obiekcie szablonu.
Zatem statyczna metoda lub atrybut również ma obiekt
Poniższe przykłady dają większą jasność między blokadą klasy i obiektu, mam nadzieję, że poniższy przykład pomoże również innym :)
Na przykład mamy poniżej metody, z których jedna uzyskuje klasę, a druga uzyskuje blokadę obiektu:
public class MultiThread {
public static synchronized void staticLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
public synchronized void objLock() throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}
Więc teraz możemy mieć następujące scenariusze:
Gdy wątki używające tego samego obiektu próbują uzyskać dostęp do metody objLock
LUB w staticLock
tym samym czasie (tj. Oba wątki próbują uzyskać dostęp do tej samej metody)
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Gdy wątki używające tego samego obiektu próbują uzyskać dostęp staticLock
i objLock
metody w tym samym czasie (próbują uzyskać dostęp do różnych metod)
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Gdy wątki używające innego obiektu Object próbują uzyskać dostęp do staticLock
metody
Thread-0 0
Thread-0 1
Thread-0 2
Thread-0 3
Thread-0 4
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Gdy wątki używające innego obiektu Object próbują uzyskać dostęp do objLock
metody
Thread-0 0
Thread-1 0
Thread-0 1
Thread-1 1
Thread-0 2
Thread-1 2
Thread-1 3
Thread-0 3
Thread-0 4
Thread-1 4
Dla tych, którzy nie są zaznajomieni ze statyczną metodą synchronizowaną zablokowaną na obiekcie klasy, np. Dla klasy string, jej String.class, podczas gdy instancja synchronizowana metoda blokuje bieżącą instancję Object oznaczoną słowem kluczowym „this” w Javie. Ponieważ oba te obiekty są różne, mają różne blokady, więc gdy jeden wątek wykonuje statyczną metodę zsynchronizowaną, inny wątek w java nie musi czekać na powrót tego wątku, zamiast tego uzyska oddzielną blokadę oznaczoną bajtem. Class i wejdzie do statyczna metoda synchroniczna.