2011-01-10 12 views
1

このJavaコードで問題を見つけるのは難しいですが、見つけられません。スレッドグループをループする - デバッグの手助けをしてください

私が提供するコードで十分ですが、必要に応じてさらに投稿します。

さらにお詫び申し上げますが、私は最小限の例を作りませんでした。

java.lang.ThreadGroupの[名前=プレーヤー、MAXPRI = 10]
プレーヤー-0:113
プレーヤー-1:277

game.getGroupPlayers().list(); 
MoverThread[] playerThread = game.getPlayers(); 
System.out.println(playerThread.length); 
for (int i = 0; i < playerThread.length; i++) { 
    try { 
     System.out.println(i + " -> " +playerThread[i].toString()); 
     returnString += playerThread[i].toString() + "\n"; 
    } catch(NullPointerException e) { 
     System.out.println("Problem at i = " + i); 
     e.printStackTrace(); 
    } 
    game.getGroupPlayers().list(); 
} 

は時々私に次のような出力を提供しますプレイヤー-2:0
0 - >プレイヤー-0:113
1 - >プレーヤー-1:277
問題Player.checkGoal(Player.java:61)でReferee.goalFound(Referee.java:70)
DebugTestReferee.goalFoundで (DebugTestReferee.java:42)
で、I = 2
java.lang.NullPointerExceptionが

Player.runで (Player.java:94)
java.lang.Thread.runで (Thread.java:636)
java.lang.ThreadGroupの[名前=プレーヤー、MAXPRI = 10]
Player- 0:113
Player-1:277
Player-2:0

[編集] ここgetPlayers()のソースだ

/* 
* post returns the games players as an array 
*/ 
public MoverThread[] getPlayers() { 
synchronized(movers) { 
    MoverThread[] playerList = new MoverThread[players.activeCount()]; 
    players.enumerate(playerList); 
    return playerList; 
} 
} 

[編集] は、ここでは、プレイヤーが生成される方法です

private ThreadGroup movers; 
private ThreadGroup players; 
private ThreadGroup ghosts; 

private Observer observer; 

/* 
* constructor 
*/ 
public Game(Maze maze, Referee referee) { 
this.maze = maze; 
this.referee = referee; 
threadList = new ArrayList<MoverThread>(); 
movers = new ThreadGroup("Movers"); 
players = new ThreadGroup(movers, "Players"); 
ghosts = new ThreadGroup(movers, "Ghosts"); 
observer = null; 
} 

[編集]

ここ

は、私が呼び出す方法です問題を生成する方法:

/* 
* post checks if the players thread was interrupted - if not if hostfield pretends to be a goal the game gets stopped and referee is called to perform "goal-found-actions" 
*/ 
private void checkGoal() { 
if (!getThread().isInterrupted()) { 
    synchronized(getGame().getMovers()) { 
     if (!getThread().isInterrupted()) { 
      if (getHostField().isGoal()) { 
       Field goal = getHostField(); 
       getGame().getReferee().goalFound(this, goal); 
       getGame().setGameOver(); 
      } 
     } 
    } 
} 
} 

、ここで全体goalFound('S)

/* 
* post action to be performed if a player finds a goal 
* print some information 
*/ 
public void goalFound(Player player, Field at) { 
//FIXME get the Bug!!! 
String returnString = "Game over - player " + player.getName() + " found a goal on (" + at.getPos()[0] + ", " + at.getPos()[1] + ")!\n"; 
game.getGroupPlayers().list(); 
MoverThread[] playerThread = game.getPlayers(); 
System.out.println(playerThread.length); 
for (int i = 0; i < playerThread.length; i++) { 
    try { 
     System.out.println(i + " -> " +playerThread[i].toString()); 
     returnString += playerThread[i].toString() + "\n"; 
    } catch(NullPointerException e) { 
     System.out.println("Problem at i = " + i); 
     e.printStackTrace(); 
    } 
} 
game.getGroupPlayers().list(); 
returnString += game.mazeString(); 
System.out.println(returnString); 
} 
+0

このループから呼び出されたコードでは例外がスローされません...他のスレッドのいずれかで例外が発生していることが表示され、ループの出力と同時に出力されているようです。 NPEが投げられているクラス 'Referee'ライン70を見てください。 –

+0

Referee.java行70は です。System.out.println(i + " - >" + playerThread [i] .toString()); – speendo

答えて

0

私は解決策を見つけた - 回避策をか多分もっと...

のArrayList aswellに私は私のスレッドを格納するスレッドグループを使用して横に(多分ベクターはさらに良くなるだろうが、私は、ArrayListにして大丈夫ですよ) 。

なぜか分かりませんが、スレッドグループ内のすべてのスレッドを呼び出そうとすると、スレッドが残っていることがよくあります。しかし、ArrayListでは正常に動作します。

ThreadGroupsが想定したとおりに動作しない理由と、この場合に必要なものは興味深いでしょう。

1

game.getPlayers();は長さ3でMoverThread[]を返しているが、3つ目はnullあります。

+0

いや、それはエラーのことです。しかし、それはできません...編集 – speendo

+1

を参照してくださいそれで 'players.enumerate(playerList);'は第3のものを設定していないものです。 –

+0

最初に私はあなたの助けを非常に感謝したいと言いたい。 プレーヤーはスレッドグループです(私のポストにすぐに追加します)ので、players.enumerate(list)は標準的なJavaメソッドにする必要があります。 – speendo

3

ThreadThreadGroupを列挙する良い方法はありません。それはよく知られているひどいデザインです。

ThreadGroup.activeCountThreadGroup.enumerate(Thread[])の間でスレッドが開始されたか、または終了した可能性があります。あなたができる最善の方法は、配列を割り当てるときにファジィファクタであるactiveCountを追加することです。返された値が配列の長さと一致する場合は、いくつか見逃している可能性があり、より大きな配列サイズで繰り返す必要があります(単なる定数を追加するのではなく、成功すると、配列を適切にトリムする必要があります(またはそのように扱う)。

+0

私はどんなソリューションにもオープンしています! 特定のケースでは、2つの理由のため、スレッドが開始または終了してはいけません。1.スレッドはプログラムの最初にのみ生成され、スレッドはプログラムの最後にのみ終了します2.ムーバーが同期されているときにこのメソッドを呼び出します(ソースを編集して表示します)。しかし、これが私の問題を解決できるかどうかは教えてください! – speendo

+0

私は、 'ThreadGroup'をロックすることのセマンティクスが定義されているとは思いません。サン/オラクルの 'Thread'実装では、動作は予期せぬものです。ジェネリックに 'Thread'を拡張するのは悪い考えですが、' ThreadGroup'を使うのは良い考えではありません。 'ThreadGroup.enumerate'に渡された' Thread [] '配列に' Thread'のサブタイプを使うのは少し危険です。それは未定義です。不適切な 'Thread'サブクラスが存在するとどうなりますか?(' ArrayStoreException'をスローします。 Sun/Oracleのソースの外観)。 –

+1

Blochは、* Effective Java *で 'ThreadGroup'の使用を主張しています。 http://stackoverflow.com/q/3265640/545127を参照してください。 – Raedwald

関連する問題