3

私は自分の研究でイベント駆動型プログラミングのためにJavaで戦艦ゲームを書いています。ゲームはネットワークゲームであると想定されており、1つのアプリケーションでクライアントとサーバーを作成します。

これは私のアプリケーションの構造を表す画像です: クラス図http://dl.dropbox.com/u/41993645/mvc.jpeg

要点を理解するために-私は別のスレッドとして実行され、リモートビューを担当するサーバークラスを書きたい-コントローラー通信。したがって、Serverクラスは次の責任を負います。

  • 無限ループでソケットからオブジェクトを読み取り、到着した場合は、コントローラーのBlockingQueueに入れます。
  • 'sendActionEventToView()'のようなメソッドを提供します。これにより、コントローラーはオブジェクトを別の方法(コントローラーからリモートビュー)に渡すことができます。

残念ながら、サーバースレッドを実行すると、アプリケーション全体が応答を停止します。誰かが私が間違っていることを教えてくれたら、私はとても感謝しています。これは私の意見では、サーバーコードの問題のある部分です。

/** Main Server method - responsible for reading objects
 *  and putting them in the queue if any arrived */
public void run() {
  GameEvent event;
  while(true) {
    try {
      event = (GameEvent)objectStream.readObject();
      if(event != null) eventQueue.put(event);
    } catch(ClassNotFoundException e) {
      e.printStackTrace();
    } catch(IOException e1) {
      e1.printStackTrace();
    } catch(InterruptedException e2) {
      e2.printStackTrace(); 
    }
  }
}

スレッドは「readingObject()」でハングしていると思います-ストリームにオブジェクトがない場合、どうすればプロセッサに別のスレッドに時間を与えるように強制できますか?

サーバーの残りの部分:https ://github.com/mc-suchecki/Battleships/blob/master/controller/Server.java アプリの残りの部分:https ://github.com/mc-suchecki/Battleships

よろしくお願いします。不明な点がございましたら、コメントをお願いします。そして、私の英語でごめんなさい。

4

5 に答える 5

0

通常のJavaストリームはブロックしています。これは、通常、ソケット接続ごとに2つのスレッドを使用することを意味します(双方向通信を想定)。各ソケット接続の各ストリーム(入力/出力)に1つのスレッドが割り当てられます。

于 2012-05-30T12:29:25.160 に答える
0

実際に複数のスレッドを使用している場合、1つのスレッドがブロックされると、他のスレッドが実行されます。他のスレッドに時間を与えるためにプロセッサを「強制」する必要はありません。

コードを見ると、ビューは別のスレッドに実行するのではなく、コントローラーのrunメソッドを直接呼び出します: https ://github.com/mc-suchecki/Battleships/blob/75e6cf69d081c05845f4171bf42ce096ed5247a7/view/View.java#L48を呼び出したのと同じスレッドで実行されるController'sコードcreateServer

要旨では、コンストラクター(https://gist.github.com/2835863#L46)Controllerの新しいスレッドに既に送信しています。Controller'sビューで「controller.run()」の呼び出しを削除できると思います。

于 2012-05-30T12:47:08.447 に答える
0

コードがpublicvoidrun();の場合 スレッドのstartメソッドを使用して開始された場合、readObjectはそのスレッドのみをブロックできます。

于 2012-05-30T12:52:08.403 に答える
0

runメソッドにそれ自体へのスレッドがあることを確認してください。私はあなたが1つのスレッドで多くのことをしていると思います。すべてのスレッドは実際には1つのスレッドであり、すべてソケットで待機しています。そして、彼らが(単数で)何かを読んだとき、彼らはただ戻ってソケットを再び待ちます。

IDEを使用して、必要なすべてのスレッドがあることを確認します。デバッガーを使用します。プログラムがハングしたときに一時停止し、すべてのスレッドを確認します。少なくとも2つあることを確認してください。(そうでない場合は、それが問題です。) 1つのスレッドがソケット読み取りにぶら下がっているはずです。他のものが存在する場合は、どこにぶら下がっているのかを確認し、コードがぶら下がらないように修正します。

于 2012-05-31T19:57:33.370 に答える
0

私はちょうど問題を見つけました-それはコンストラクターにありました:

/** Server class constructor */
public Server(BlockingQueue<GameEvent> queue) {
  eventQueue = queue;
  try {
    serverSocket = new ServerSocket(Constants.PORT_NUMBER);
    socket = serverSocket.accept();  
    inputStream = socket.getInputStream();  
    objectStream = new ObjectInputStream(inputStream);  
  } catch(IOException e) {
    e.printStackTrace();
  }  
  Thread thread = new Thread(this);
  thread.start();
}

別のスレッドが作成される前socket = serverSocket.accept()にアプリケーションがハングした行。理由はわかりませんが、方法の問題を探しましたが、それは間違っていました。run()

于 2012-06-02T12:36:57.987 に答える