2015-05-16 15 views
5

Chcę uruchomić dwa wątki jeden po drugim, bez użycia trybu uśpienia() lub blokady, ale dzieje się zakleszczenie! Co jest nie tak z moim kodem? Użyłem wait() i notifyAll() i obiektu Object.Zatrzymanie Java i powiadamianie sprawia, że ​​zakleszczenie

public class Test { 

    public static void main(String[] args) throws InterruptedException { 
     PrintChar a = new PrintChar('a'); 
     PrintChar b = new PrintChar('b'); 
     Thread ta = new Thread(a); 
     Thread tb = new Thread(b); 
     ta.start(); 
     tb.start(); 
    } 
} 

class PrintChar implements Runnable { 
    final Object o = new Object(); 
    char ch; 
    public PrintChar(char a) { 
     ch = a; 
    } 

    @Override 
    public void run() { 
     for (int i = 0; i < 100; i++) { 
      synchronized (o) { 
       System.out.print(ch); 
       try { 
        o.wait(); 
        o.notifyAll(); 
       } catch (InterruptedException ex) { 
       } 
      } 
     } 
    } 
} 
+2

nie rozumiem te pytania. Jeśli chcesz sekwencyjne wykonanie, dlaczego używasz wątków? – EJP

+0

Mniejsza o EJP! Po prostu ćwiczyć! – John

Odpowiedz

7

Uruchamiając Twój kod i patrząc na niego, odkryłem, że każdy wygenerowany wątek generował i synchronizował się z własnym obiektem, uniemożliwiając mu wzajemne powiadamianie. Zauważyłem również, że czekasz przed powiadomieniem, więc nie będziesz mógł nigdy wywołać o.notifyAll(), ponieważ zatrzyma go najpierw.

Zmień final Object o = new Object() do static final Object o = new Object() i zamienić miejscami o.wait() i o.notifyAll()

-1

myślę blok synchronized powoduje impasu. Ponieważ nie pozwoli on na rozpoczęcie drugiego wątku, dopóki bieżący nie zostanie zakończony. Używasz metody wait(), aby bieżący wątek czekał. Ok, będzie czekać, ale ponieważ jest w bloku synchronized, będzie w bieżącym wątku na zawsze nigdy nie pozwolił na utworzenie żadnego innego wątku z powodu synchronized.

Jedna rzecz, którą można zrobić, aby inny wątek działał, to: Thread.stop. Spróbuj wywołać stop method w odnośniku bieżącego wątku. Ale nie jestem pewien, czy pozwoli bieżącemu wątkowi zacząć od nowa.

+0

ale na pewno spowoduje to rozpoczęcie innego wątku, jak na twoje pytanie bez użycia ** sleep() ** :) – Choxx

+2

Jest to błędne, ponieważ połowa funkcji 'Object.wait()' polega na atomistycznym zwolnieniu blokady na nim zawieszonej. W rzeczywistości jest wymagane wywołanie z poziomu 'zsynchronizowanego' bloku na danym obiekcie. – Dolda2000

Powiązane problemy