3

I am writing Battleships game in Java for Event-Driven Programming on my studies. The game is supposed to be a network game and i am going to make client and server in one application.

This is an image representing structure of my application: class diagram http://dl.dropbox.com/u/41993645/mvc.jpeg

To get to the point - i want to write Server class that will run as separate thread and are responsible for remote View - Controller communication. So, the Server class will be responsible for:

  • Reading objects from socket in infinite loop and if any arrives, putting them in the BlockingQueue for the Controller.
  • Providing method like 'sendActionEventToView()' which will allow Controller to pass object the other way - from Controller to remote View.

Unfortunately, when running the Server thread, whole application stops responding. If anybody would tell me what am i doing wrong, i would be very grateful. This is in my opinion the problematic part of Server code:

/** 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(); 
    }
  }
}

I think thread hangs on 'readingObject()' - how can i force it to give processor time to another threads if there are not any objects in the stream?

Rest of Server: https://github.com/mc-suchecki/Battleships/blob/master/controller/Server.java Rest of the app: https://github.com/mc-suchecki/Battleships

Thank you very much in advance, if anything is unclear, please comment. And sorry for my English.

4

5 回答 5

0

如果你真的在使用多个线程,那么当一个线程被阻塞时,其他线程就会运行。没有必要“强制”处理器给其他线程时间。

查看您的代码,您的视图直接调用控制器的 run 方法,而不是将其交给另一个线程运行: https ://github.com/mc-suchecki/Battleships/blob/75e6cf69d081c05845f4171bf42ce096ed5247a7/view/View.java#L48这会导致Controller's要在调用的同一线程中运行的代码createServer

在您的要点中,您已经将您提交Controller给构造函数中的新线程Controller's(https://gist.github.com/2835863#L46)。我假设您可以在您的视图中删除对“controller.run()”的调用。

于 2012-05-30T12:47:08.447 回答
0

如果您的代码 public void run(); 使用 Thread 的 start 方法启动时,readObject 只能阻塞该线程。

于 2012-05-30T12:52:08.403 回答
0

确保你的run方法本身有一个线程。我怀疑您在一个线程上做了很多事情;您所有的线程实际上都是一个线程,它们都在套接字上等待。当他们(单数)读到一些东西时,他们只是回去再次等待套接字。

使用您的 IDE 确保您拥有所需的所有线程。使用您的调试器。挂起时暂停程序并检查所有线程。确保你至少有两个。(如果你不这样做,那就是问题所在。) 一个线程应该挂在读取的套接字上。检查其他人(如果存在)在哪里挂起并修复代码,以免他们不这样做。

于 2012-05-31T19:57:33.370 回答
0

正常的 java 流是阻塞的。这意味着您通常希望每个套接字连接使用 2 个线程(假设双向通信)。一个线程专门用于每个套接字连接的每个流(输入/输出)。

于 2012-05-30T12:29:25.160 回答
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 回答