Android-Thread.join () заставляет приложение зависать

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

System.out.println("YAY"); 

Моя тема для игрового цикла:

Этот поток успешно распечатывает «Game Ended», но никогда не заканчивается.

 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"); } }; в 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 () заставляет текущий поток ждать, пока новый поток не закончит, прежде чем продолжить.

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

Solutions Collecting From Web of "Android-Thread.join () заставляет приложение зависать"

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

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

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

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

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

… …

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

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

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