2015-05-16 13 views
5

Voglio eseguire due thread uno dopo l'altro, senza usare sleep() o Locks, ma si verifica un deadlock! Cosa c'è che non va nel mio codice? Ho usato wait() e notifyAll() e un oggetto Object.Java wait and notify fa deadlock

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

ho mai capito queste domande. Se vuoi l'esecuzione sequenziale, perché stai usando i thread? – EJP

+0

Non importa, EJP! Praticando! – John

risposta

7

Eseguendo il codice, e osservandolo, ho trovato che ogni thread che hai generato stava generando e sincronizzando il suo stesso oggetto, impedendo quindi loro di notificarsi a vicenda. Ho anche scoperto che aspetti prima di notificare, in modo da non invocare mai o.notifyAll(), poiché o.wait() lo interrompe per primo.

Change final Object o = new Object() a static final Object o = new Object(), e modificare le posizioni delle o.wait() e o.notifyAll()

-1

penso che il blocco synchronized è la causa del stallo. Cos non lascerà che l'altro thread cominci fino a che quello attuale non sia finito. Si sta utilizzando il metodo wait() per attendere il thread corrente. Ok, aspetterà ma siccome è nel blocco synchronized, sarà sempre nel thread corrente per non lasciare mai che nessun altro thread sia venuto in esistenza a causa di synchronized.

Una cosa che puoi fare per far funzionare l'altro thread è usare Thread.stop. Prova a chiamare stop method nel riferimento del thread corrente. Ma non sono sicuro che lascerà che il thread corrente ricomincia.

+0

ma sicuramente questo inizierà altri thread come da domanda senza usare ** sleep() ** :) – Choxx

+2

Questo è sbagliato, poiché metà della funzione di 'Object.wait()' è di rilasciare atomicamente il blocco su di esso. In realtà è necessario essere chiamato da un blocco "sincronizzato" sull'oggetto in questione. – Dolda2000