2010-03-28 12 views
8

Zgodnie z Java thread state info wywołanie wait() spowoduje przejście wątku w stan BLOCKED. Jednak ten fragment kodu będzie (po wywołaniu) w wątku w stanie oczekiwania.Java Thread wait() => blocked?

class bThread extends Thread { 
    public synchronized void run() { 
     try { 
      wait(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

Czy coś jest nie tak? Czy ktoś może mi wyjaśnić to zachowanie? Każda pomoc będzie doceniona!

+0

Uwaga boczna: Powiąż połączenie oczekujące z warunkiem. – zgulser

Odpowiedz

15

Wątek jest WAITING, dopóki nie zostanie powiadomiony. Następnie staje się BLOCKED, próbując ponownie wprowadzić zsynchronizowany region, dopóki wszystkie pozostałe wątki nie zostaną.

Odnośne części z linku pisał (czekanie):

Na przykład wątku, który powołał Object.wait() na obiekcie czeka na innym wątku zadzwonić Object.notify() lub Object.notifyAll() na tym obiekcie.

oraz (blokadą)

Gwint w stanie zblokowanym czeka na blokadę monitora do [...] ponownie wejść bloku zsynchronizowanego/metoda po wywołaniu Object.wait.

Ostatnia część występuje, gdy wątek próbuje powrócić z wait(), ale nie do tego czasu.

+0

oznacza, że ​​zablokowany wątek jest w pętli, aby uzyskać blokadę? aka wątek w zablokowanym stanie koszt czasu procesora? – user2807219

+0

@ user2807219: Nie, zazwyczaj nie. Wątek znajdowałby się w gotowej kolejce muteksu chroniącego zsynchronizowany region, tak samo jak w przypadku wywoływania zsynchronizowanej funkcji zablokowanej przez inny wątek. Głównym problemem, z którym należy się zmagać z rywalizacją blokad, jest zazwyczaj wymuszanie przełączników kontekstu na programie (tj. Przechowywanie i przywracanie stanu działającego wątku w CPU), które są względnie kosztowne. –

1

Oczekiwanie jest wtedy, gdy nic nie robi. Zablokowane jest, gdy próbuje ponownie zacząć działać, ale nie zostało jeszcze dozwolone.

3

Gdzie widziałeś takie rzeczy?

Na tej samej stronie możesz powiązane, thread.state, wyraźnie stwierdza, że ​​

oczekiwania będzie po Object.wait()

ZABLOKOWANY będzie przed wejściem zsynchronizowane

+0

Och, widzę, co mogło cię zdezorientować. "BLOCKED => lub ponownie wprowadź zsynchronizowany blok/metodę po wywołaniu Object.wait." .. zauważ "wróć do zsynchronizowanego bloku" –

9

Monitor wykonuje jeden wątek na czas. Zakładając, że masz wątki T1-T10, 9 to BLOCKED, a jeden to RUNNABLE. Co jakiś czas monitor wybiera nowy wątek do uruchomienia. Kiedy tak się dzieje, wybrany/bieżący wątek, powiedzmy T1, przechodzi od RUNNABLE do BLOCKED. Kolejny wątek, na przykład T2, przechodzi z BLOCKED do RUNNABLE, stając się bieżącym wątkiem.

Gdy jeden z wątków potrzebuje informacji do udostępnienia przez inny wątek, należy użyć wait(). W takim przypadku wątek zostanie oznaczony jako WAITING, dopóki nie zostanie zmieniony na notify(). Tak więc wątek, który czeka, nie zostanie wykonany przez monitor do tego czasu. Przykładem może być: poczekaj, aż zostaną rozładowane skrzynki. Pola ładujące faceta powiadomią mnie, kiedy to się stanie.

Innymi słowy, zarówno BLOCKED i WAITING są status nieaktywnych wątków, ale WAITING wątek nie może być RUNNABLE bez przechodzenia do BLOCKED pierwszy. WAITING wątki "nie chcę" stają się aktywne, podczas gdy BLOCKED wątki "chcą", ale nie mogą, ponieważ nie jest ich kolej.

Myślę.

0

Przypominamy, że powinieneś zawsze wywoływać funkcję wait() w pętli while, czekając na warunek wejścia w zsynchronizowany region/sekcję krytyczną. Jest tak dlatego, że Java ma "fałszywe wybudzenia" (w zasadzie wątek może w każdej chwili się obudzić bez żadnego powodu).

1

Jest tu trochę mylącej terminologii. Gdy wątek wywołuje wait na obiekcie, przechodzi w stan oczekiwania. Gdy wątki są czekają na pobranie blokady, należą do zestawu wait dla tej blokady, ale znajdują się w stanie BLOCKED.

Mylące, ale jakoś to ma sens!