Jaka jest różnica między stanem wątku WAIT a stanem wątku ZABLOKOWANY?
Dokumentacja Thread.State :
Zablokowany
Wątek, który jest zablokowany i oczekuje na blokadę monitora, jest w tym stanie.Oczekiwanie
W tym stanie jest wątek, który czeka w nieskończoność na wykonanie określonej czynności przez inny wątek
nie wyjaśnia mi różnicy.
java
multithreading
block
wait
Więcej niż pięć
źródło
źródło
Odpowiedzi:
Wątek przechodzi w stan oczekiwania po wywołaniu
wait()
obiektu. Nazywa się to stanem oczekiwania . Gdy wątek osiągnie stan oczekiwania, będzie musiał poczekać, aż inne wywołania wątkunotify()
lubnotifyAll()
obiekt.Po powiadomieniu tego wątku nie będzie można go uruchomić. Może się zdarzyć, że inne wątki również są powiadamiane (używają
notifyAll()
) lub pierwszy wątek nie zakończył swojej pracy, więc nadal jest blokowany, dopóki nie dostanie swojej szansy. Nazywa się to stanem zablokowanym . Stan Zablokowany wystąpi, gdy wątek spróbuje uzyskać blokadę obiektu, a inny wątek już utrzymuje blokadę.Po opuszczeniu innych wątków i uzyskaniu tej szansy na wątek, przechodzi on do stanu Runnable, po czym kwalifikuje się do podjęcia pracy w oparciu o mechanizm wątków JVM i przechodzi do stanu uruchomienia.
źródło
Różnica jest stosunkowo prosta.
W tym
BLOCKED
stanie wątek ma zamiar wejść dosynchronized
bloku, ale obecnie wsynchronized
bloku tego samego obiektu działa inny wątek . Pierwszy wątek musi następnie czekać, aż drugi wątek opuści swój blok.W tym
WAITING
stanie wątek oczekuje na sygnał z innego wątku. Dzieje się to zwykle przez telefonObject.wait()
lubThread.join()
. Wątek pozostanie w tym stanie do czasu wywołania innego wątkuObject.notify()
lub śmierci.źródło
Object.wait()
bezpośrednio, ale kończysz wWAITING
stanie również przy użyciu konstrukcji współbieżności wyższego poziomu - takich jak blokady, kolejki blokujące itp., Mówiąc ogólnie, gdy dwa wątki muszą koordynować.RUNNING
stanie.Thread.State
mówi: „... Te stany to stany maszyny wirtualnej, które nie odzwierciedlają żadnych stanów wątków systemu operacyjnego”. Innymi słowy, maszyna JVM nie dba o różnicę między wątkiem, w którym działa kod Java, wątkiem oczekującym na zwrot wywołania systemowego, a wątkiem oczekującym na wycinek czasu. To wszystkoRUNNABLE
dotyczy JVM.WAITING
stanu, musi najpierw przejść do tegoBLOCKED
stanu, aż będzie mógł uzyskać blokadę związaną z obiektem, na który czekał.Ważną różnicą między stanami zablokowanymi i oczekującymi jest wpływ na harmonogram. Wątek w stanie zablokowanym walczy o blokadę; ten wątek nadal liczy się jako coś, co planista musi obsłużyć, prawdopodobnie biorąc pod uwagę decyzje planisty dotyczące tego, ile czasu ma dać działającym wątkom (aby mógł dać wątkom blokowanie blokady).
Gdy wątek znajduje się w stanie oczekiwania, obciążenie systemu jest zminimalizowane, a planista nie musi się tym martwić. Przechodzi w stan uśpienia, dopóki nie otrzyma powiadomienia. Z wyjątkiem faktu, że utrzymuje zajęty wątek systemu operacyjnego, jest całkowicie poza grą.
To dlatego użycie notifyAll jest mniej niż idealne, powoduje, że kilka wątków, które wcześniej były szczęśliwie uśpione, nie obciążały systemu, aby się obudzić, gdzie większość z nich będzie blokować, dopóki nie zdobędą blokady, znajdą stan, w którym są czekanie nie jest prawdą i wróć do czekania. Lepiej byłoby powiadamiać tylko te wątki, które mają szansę na postęp.
(Użycie ReentrantLock zamiast wewnętrznych blokad pozwala mieć wiele warunków dla jednej blokady, dzięki czemu można upewnić się, że powiadomiony wątek jest tym, który czeka na określony warunek, unikając błędu zgubienia powiadomienia w przypadku powiadomienia o wątku coś, na co nie może działać.)
źródło
Uproszczona perspektywa interpretacji zrzutów wątków:
źródło
RUNNABLE
nie jest całkiem w porządku. Może znajdować się w kolejce uruchomień języka Java, ale nie może być wykonywany lub może wykonywać kod Java. Nie musi to być wołanie do ojczyzny.Zablokowany - Twój wątek znajduje się w stanie gotowości do uruchomienia i próbuje uzyskać blokadę obiektu. Czekaj - Twój wątek jest w stanie oczekiwania na cykl życia wątku i czeka na sygnał powiadamiający, aby przejść w stan gotowości wątku do uruchomienia.
źródło
zobacz ten przykład:
demonstracja stanów wątku.
źródło