2014-11-02 11 views
7

Myślę, że już znam odpowiedź na to pytanie, jednak chciałbym przeczytać wasze opinie, aby upewnić się, że naprawdę rozumiem, jak działa automat stanowy (lub schemat) java wątku.java: Jeśli powiadomienie() jest zawsze wywoływane przed zwolnieniem blokady, w jaki sposób oczekujące wątki mogą uzyskać tę samą blokadę?

Wyobraźmy sobie, że nawlec uruchamia powiadomić() tuż przed powrotem daną wartość:

public class baz{ 

    // Thread B runs this: 
    public synchronized void bar(){ 
     wait(); 
    } 

    // Thread A runs this: 
    public synchronized int foo(){ 
     notify(); 
     return 11; 
    } 
} 

powiadomić() zostanie wezwany przed nawlec zwalnia blokadę (zdarza się, że wola „po” instrukcja return 11; W jaki sposób wątek B, który czeka na tę blokadę (za pomocą metody wait()), uzyskuje blokadę, która wciąż jest utrzymywana przez wątek A? zauważyć, że gdy wątek B jest powiadamiany zamek nie został jeszcze wydany przez wątek A.

Więc co myślę o tej sytuacji jest następujący:

Po wywołaniu wait(), gwint B będzie zmień jego stan z Running na Oczekiwanie na. Po otrzymaniu powiadomienia (od nawlec powiadomić() metoda), gwint B powróci z wait(), zmienić swój stan do Runnable i starają się zdobyć zamek. Ponieważ blokada nie została jeszcze zwolniona przez wątek A, wątek B zostanie zablokowany na monitorze obiektu i przejdzie jego stan z Runnable do Zablokowany. Ostatecznie, po tym, jak wątek A zwalnia blokadę, wątek B zdobędzie blokadę i przejdzie jej stan z Zablokowany na Działający.

Czy to prawda? Co chcę zrozumieć z tym pytaniem jest co stanie się z wątkiem, który powraca z wait(), który jest synchronizowany przez już pozyskaną blokadę.

Odpowiedz

1

Tak, twoje wyjaśnienie jest poprawne.

Po wywołaniu wait() na obiekcie, wątek wywołujący zostanie dodany do obiektu wait set. Gdy będzie to notify(), zostanie usunięte z tego zestawu oczekiwania i wykona na nim obiekt a lock action (znajduje się w bloku synchronized na tym obiekcie). Ta blokada zablokuje bieżący wątek, dopóki nie zostanie ukończony, tj. zablokował monitor obiektu.

To jest dokładnie to samo zachowanie, które miałyby dwa wątki podczas próby wprowadzenia bloku synchronized na tym samym obiekcie. Pierwszy wątek do osiągnięcia zablokuje monitor obiektu, natychmiast zamykając obiekt blokady. Drugi wątek blokuje, dopóki jego działanie blokujące nie zostanie zakończone, tj. po pierwszym wątku odblokowuje monitor.

+0

to znaczy, że zwrotne oświadczenie nie może zwolnić blokady? a przykładem pytania może być DeadLock? i nie powinniśmy używać instrukcji return w metodzie zsynchronizowanej? czy możesz wyjaśnić proszę lub podać mi link, który mógłby wyjaśnić moje koncepcje. – UnKnown

+0

@UnKnown 'return', sam w sobie, nie zwalnia blokady.Jeśli pojawi się instrukcja 'return' z' zsynchronizowanym 'blokiem lub metodą, jest to akcja wywołana przez' return', czyli. pozostawiając ten blok lub metodę, która zwolni blokadę. –

Powiązane problemy