2013-04-12 12 views
7

Ho una discussione che gestisce il mio ciclo di gioco, quando chiamo .join() su questo thread l'applicazione smette di rispondere. Ho cercato di risolvere un problema in cui i programmi non arrivano mai al codice, I.E il thread non finisce mai.Android- Thread.join() fa sì che l'applicazione si blocchi

System.out.println("YAY"); 

mio thread per il Game Loop:

Questo thread stampa con successo "partita si è conclusa", ma non sembra mai finire.

Runnable startGameLoop = new Runnable() {//game loop 
      @Override 
      public void run() { 

       AiFactory ai = new AiFactory(); 
       final Button play = (Button) findViewById(R.id.Play); 
       final Button pass = (Button) findViewById(R.id.Pass); 

       while(finish==false){ 
        try { 
         Thread.sleep(500); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        currentPlayer = game.getPlayer(); 

        if(currentPlayer.isPlayer()==false){ 

         //System.out.println("passCount:" +game.getPasscount()); 
         ai.decide(nextPlay, game.getPreviousPlayed(), currentPlayer, game.getPasscount()); 
         if(nextPlay.size()!=0){ 
          runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           if(nextPlay.size() ==1){ 
            play1Card(); 
           } 
           else if(nextPlay.size()==2){ 
            play2Card(); 
           } 
           else if(nextPlay.size()==3){ 
            play3Card(); 
           } 
           else if(nextPlay.size()==5){ 
            play5Card(); 
           } 
          } 
         } 
         else{ 
          game.addPassCount(); 
          game.nextTurn(); 
          runOnUiThread(new Runnable(){ 
           public void run(){ 
            changeArrow(); 
           } 
          }); 
         }  
        } 
        else if (currentPlayer.isPlayer()==true){ 
         runOnUiThread(new Runnable(){ 
          public void run(){ 
           changeArrow(); 
           play.setClickable(true); 
           if(game.getPasscount()==3){ 
            pass.setClickable(false); 
           } 
           else{ 
            pass.setClickable(true); 
           } 
          } 
         }); 
        } 

      } 
      System.out.println("Game Ended"); 
      } 
    }; 

Avvio e partecipazione il filo per il filo conduttore:

 Thread myThread = new Thread(startGameLoop); 

    myThread.start(); 
    try { 
     myThread.join(); 
    } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    System.out.println("YAY"); 
} 

Per la mia comprensione .join() rende il thread corrente di attesa fino al nuovo thread ha finito prima di continuare.

Scusate se questa è una domanda stupida, sono abbastanza nuovo per il threading.

+2

Abbiamo bisogno di un po 'più di contesto. Dove si presenta questa chiamata a 'join()'. Molto probabilmente lo stai facendo sul thread dell'interfaccia utente che spiegherebbe il motivo per cui la tua app si blocca. –

+0

join si verifica in onCreate() in una classe di attività –

+0

Quindi la tua app è in attesa che un thread termini prima che termini la creazione dell'attività. È questo * veramente * quello che vuoi fare? Se no, cosa * stai * stai cercando di fare qui? –

risposta

5

Quando si chiama myThread.join() all'interno di Activity.onCreate si blocca il thread dell'interfaccia utente principale. Ovviamente sembra che la tua applicazione stia rispondendo perché il thread dell'interfaccia utente è quello responsabile del ridisegno dell'interfaccia utente (duh). Tutte le chiamate runOnUiThread non si verificano mai perché il thread dell'interfaccia utente è occupato in attesa del ciclo di gioco.

5

Thread.join fa in modo che il thread corrente attenda fino al termine del thread su cui viene chiamato. Non causa la fine del thread su cui viene chiamato. Quindi, se quel thread non finisce mai (come dici tu all'inizio), chiamare join lo renderà sospeso per sempre.

Se si desidera terminare effettivamente il thread, chiamare Annulla su di esso. Ma ciò richiede che la tua discussione occasionalmente chiami isCanceled() ed esca dalla sua funzione run se restituisce true.

1

mythread.join() non garantisce la fine del "mythread".

È necessario inserire una notifica() nel ciclo di gioco.

... ...

System.out.println("Game Ended"); 
synchronized(mythread){ 
    mythread.notify(); 
} 

In sostanza, quando si effettua una chiamata a wait(), il codice attende sul monitor del thread, e una chiamata di notifica() causa un thread in attesa su il monitor dell'oggetto per svegliarsi. Inoltre, è possibile utilizzare notifyAll() per riattivare tutti i thread in attesa.

In alternativa, è possibile utilizzare la versione di attesa di attesa(), in cui il thread attende fino a quando non viene notificato o scade.

+0

Faresti meglio a usare 'Lock' con' Condition' per ottenere questo risultato –

Problemi correlati