Napisałem aplikację testową, która nigdy nie powinna się zatrzymać. Wydaje obiekt t.wait()
(t
jest obiektem Thread
), ale nigdy nie wywołuję powiadomień. Dlaczego ten kod się kończy? Pomimo synchronizacji głównego wątku na t
, wątek z wątku jest uruchamiany, więc nie blokuje tego obiektu.Czy Java niejawnie powiadamia o oczekujących wątkach?
public class ThreadWait {
public static void main(String sArgs[]) throws InterruptedException {
System.out.println("hello");
Thread t = new MyThread();
synchronized (t) {
t.start();
Thread.sleep(5000);
t.wait();
java.lang.System.out.println("main done");
}
}
}
class MyThread extends Thread {
public void run() {
for (int i = 1; i <= 5; i++) {
java.lang.System.out.println("" + i);
try {
Thread.sleep(500);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
Powoduje to, że wątek główny czeka 5 sekund i podczas tego czasu pracownik daje wynik. Następnie po 5 sekundach kończy się program. t.wait()
nie czeka. Jeśli główny wątek nie przespałby się przez 5 sekund (komentując tę linię), wówczas t.wait()
faktycznie czekałby aż robot zakończy pracę. Oczywiście, tutaj jest metoda join()
, ale nieoczekiwanie, wait()
robi to samo co join()
. Czemu?
Może JVM widzi, że ponieważ działa tylko jeden wątek, nie ma możliwości powiadomienia głównego wątku i rozwiązania zakleszczenia. Jeśli to prawda, czy jest to udokumentowana funkcja?
Mam testowanie w systemie Windows XP, Java 6.
Co dzieje się, gdy śpisz tylko przez 1 lub 2 sekundy? Założę się, że główny wątek będzie czekał na zakończenie wątku t ... – Renato