2013-04-12 2 views
7

У меня есть поток, который обрабатывает мой игровой цикл, когда я вызываю .join() в этом потоке, приложение перестает отвечать на запросы. Я пытался исправить проблему, когда программы никогда не попадают в код, I.E нить никогда не заканчивается.Android-Thread.join() вызывает приложение для зависания

System.out.println("YAY"); 

Моя тема для Loop игры:

Эта нить успешно печатает «Игра закончилась», но кажется, никогда не закончить.

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"); 
      } 
    }; 

и присоединение нить к главной теме:

 Thread myThread = new Thread(startGameLoop); 

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

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

В моем понимании .join() делает текущий поток в состояние ожидания до нового потока закончил перед продолжением.

Извините, если это глупый вопрос, я новичок в потоковом режиме.

+2

Нам нужно немного больше контекста. Где это происходит при вызове 'join()'. Скорее всего, вы делаете это в потоке пользовательского интерфейса, что объясняет, почему ваше приложение зависает. –

+0

соединение происходит в onCreate() в классе активности –

+0

Итак, ваше приложение ожидает завершения потока, прежде чем он завершит создание Activity. Действительно ли это, что вы хотите сделать? Если нет, то что * * вы пытаетесь сделать здесь? –

ответ

5

Когда вы вызываете myThread.join() внутри Activity.onCreate, вы блокируете основной поток пользовательского интерфейса. Конечно, похоже, что ваше приложение перестает отвечать, потому что поток пользовательского интерфейса является ответственным за перерисовку пользовательского интерфейса (duh). Все ваши звонки runOnUiThread никогда не случаются, потому что ваш поток пользовательского интерфейса занят, ожидая вашего игрового цикла.

5

Thread.join заставляет текущий поток ждать, пока поток вы не назовете его концами. Это не приводит к тому, что поток, который вы вызываете, заканчивается. Поэтому, если этот поток никогда не заканчивается (как вы говорите в верхней части), вызов соединения заставит его висеть навсегда.

Если вы хотите на самом деле закончить поток, отмените его. Но для этого требуется, чтобы ваш поток иногда вызывал isCanceled() и выходил из функции запуска, если он возвращает true.

1

mythread.join() не гарантирует, что ваш «мифот» закончился.

Вам необходимо указать оповещение() в своем игровом цикле.

... ...

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

В основном, когда вы делаете вызов ждать(), код ожидает на мониторе потока, и вызов уведомить() вызывает поток, ожидающий на монитор объекта для пробуждения. Кроме того, вы можете использовать notifyAll() для пробуждения всех ожидающих потоков.

В качестве альтернативы вы можете использовать версию ожидания wait(), где поток ожидает либо до тех пор, пока не получит уведомление, а истечет время ожидания.

+0

Вам лучше использовать 'Lock' с' Condition', чтобы лучше достичь этого –

Смежные вопросы