10

ゲーム ループを処理するスレッドがあります。このスレッドで .join() を呼び出すと、アプリケーションが応答しなくなります。プログラムがコードに到達しない、つまりスレッドが終了しないという問題を修正しようとしています。

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

スレッドの開始とメインスレッドへの参加:

     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() は、新しいスレッドが完了するまで現在のスレッドを待機させてから続行します。

これがばかげた質問である場合は申し訳ありませんが、私はスレッドにまったく慣れていません。

4

3 に答える 3

7

Thread.join は、呼び出したスレッドが終了するまで現在のスレッドを待機させます。呼び出したスレッドが終了することはありません。したがって、そのスレッドが終了しない場合 (上で述べたように)、join を呼び出すとスレッドが永久にハングします。

実際にスレッドを終了したい場合は、cancel を呼び出します。ただし、それには、スレッドが isCanceled() をときどき呼び出して、true が返された場合に run 関数を終了する必要があります。

于 2013-04-12T03:41:21.093 に答える
6

myThread.join()内部で呼び出すとActivity.onCreate、メイン UI スレッドがブロックされます。もちろん、UI スレッドが UI の再描画を担当しているため、アプリケーションが応答を停止したように見えます。runOnUiThreadUI スレッドがゲーム ループで待機中のため、すべての呼び出しが発生することはありません。

于 2013-04-12T05:23:23.600 に答える
1

mythread.join() does not ensure that your "mythread" is ended.

You need to place a notify() in your game loop.

... ...

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

Basically, when you make a call to wait(), the code waits on the thread's monitor, and a call to notify() causes a thread waiting on the object's monitor to wake up. Also, you can use notifyAll() to wake up all the waiting threads.

Alternatively, you can use timeout version of wait(), where the thread waits either till it gets notified or it times out.

于 2013-04-12T04:46:38.973 に答える