2010-07-06 10 views
8

Nauczyłem się, że wywołanie metody obiektu wait() spowoduje zwolnienie monitora obiektu, jeśli jest obecny.java: wait(), notify() i zsynchronizowane bloki

Ale mam kilka pytań dotyczących nazywając notify() na tym obiekcie przez inny wątek:

  1. (kiedy) będzie obudzić wątek czeka, jeśli inny (3rd) gwint posiada monitor obiektu w międzyczasie ?

  2. czy wątek oczekujący się obudzi, czy trzeci wątek o nazwie wait() na tym obiekcie?

  3. jest to możliwe do ustalenia, czy wątek czeka na powiadamianie konkretny obiekt (Java 1.4/java 5)

  4. Co się dzieje, jeśli wait() zostanie wywołana w metodzie finalize()?

Odpowiedz

2
  1. notify obudzi oczekujący na monitorze jeden wątek. Dopóki monitor nie zostanie naniesiony, nie można uruchomić wątku oczekiwania; funkcja wait() musi zostać wywołana w zsynchronizowanym bloku i dlatego blokada musi zostać wstrzymana, aby kontynuować działanie tego bloku.
  2. Brak gwarancji. Zadzwoń pod numer notifyAll, aby nadać wszystkim wątkom szansę na przebudzenie.
  3. Dunno. Możesz ustawić zmienną wątku, mówiąc, że czeka przed pójściem spać ...
  4. To chyba zły pomysł. Czy możesz wymyślić sytuację, w której jest to konieczne?
+0

1. "wait() musi być wywołany w zsynchronizowanym bloku" jest błędne. Ale powinno. 2. Tak, masz rację. 3. Myślę, że Chris Denett jest tutaj. Thread.holdsLock() brzmi dobrze. 4. To było bardziej teoretyczne pytanie, aby zrozumieć pojęcia. – MRalwasser

+1

@MRalwasser: Nie zgadzam się, musi. Zajrzyj tutaj: http://stackoverflow.com/questions/2779484/why-must-wait-always-be-in-synchronized-block/ – Marcus

2
  1. Dlatego trzeba metod notify() i notifyAll(). Pierwszy budzi jeden wątek oczekujący na obiekt, drugi budzi wszystkie wątki. Oczekujący wątek nie obudzi się, jeśli zostanie wywołany w innym wątku.

  2. nr

  3. Jest to możliwe tylko zadzwonić thread.holdsLock(obj) aby sprawdzić, czy gwint posiada blokadę monitora w danym obiekcie.

  4. Nie wywołuj wait() w metodzie finalizacji.

+0

Akceptuję 2.-4. ale twoja odpowiedź na 1. jest zła. Mówię o monitorze blokady (zsynchronizowanych blokach) – MRalwasser

0

2: Niekoniecznie. notify() budzi się jeden oczekujących wątków. Może być oryginalny lub trzeci.

3: Używając thread.getState() możesz dowiedzieć się, czy wątek czeka na obiekt, ale nie wiem, czy zawsze możesz dowiedzieć się, który to dokładnie obiekt.

3

Po wywołaniu wait() z wątku, ten wątek zatrzymuje wykonywanie i jest dodawany do zestawu oczekiwania obiektu. Kiedy wywołasz notify() z innego wątku, budzi się losowy wątek z zestawu wait, jeśli wywołasz notifyAll() wszystkie będą gotowe do wykonania.

Po wywołaniu notify() wątek jest gotowy do uruchomienia, ale nie oznacza, że ​​będzie wykonywany natychmiast, więc zachowaj ostrożność.

  1. Budził wątek losowo z zestawu oczekiwania.

  2. Nie wiesz, który z nich zostanie przebudzony jako pierwszy, nie wykonuje żadnej kolejności.

  3. Thread.getState()

  4. Można by produkować impasu.