Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-创建用于通过Internet发送对象的独立线程_Java_Multithreading_Sockets_Event Handling_Connection - Fatal编程技术网

Java-创建用于通过Internet发送对象的独立线程

Java-创建用于通过Internet发送对象的独立线程,java,multithreading,sockets,event-handling,connection,Java,Multithreading,Sockets,Event Handling,Connection,我正在用Java编写战舰游戏,用于学习事件驱动编程。这个游戏应该是一个网络游戏,我将在一个应用程序中创建客户端和服务器 这是表示我的应用程序结构的图像: 为了切入点,我想编写一个服务器类,它将作为单独的线程运行,并负责远程视图-控制器通信。因此,服务器类将负责: 在无限循环中从套接字读取对象,如果有对象到达, 将它们放入控制器的阻塞队列中 提供类似“sendActionEventToView()”的方法,该方法允许控制器以另一种方式传递对象—从控制器传递到远程视图 不幸的是,当运行服务器线

我正在用Java编写战舰游戏,用于学习事件驱动编程。这个游戏应该是一个网络游戏,我将在一个应用程序中创建客户端和服务器

这是表示我的应用程序结构的图像:

为了切入点,我想编写一个服务器类,它将作为单独的线程运行,并负责远程视图-控制器通信。因此,服务器类将负责:

  • 在无限循环中从套接字读取对象,如果有对象到达, 将它们放入控制器的阻塞队列中
  • 提供类似“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()”——如果流中没有任何对象,我如何强制它给其他线程提供处理器时间

服务器的其余部分: 应用程序的其余部分:


提前非常感谢,如果有任何不清楚的地方,请评论。对不起,我的英语不好。

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

如果您确实使用多个线程,那么当一个线程被阻塞时,其他线程将运行。不需要“强制”处理器给其他线程时间

查看您的代码,您的视图直接调用控制器的run方法,而不是将其交给另一个线程运行: 这将导致
控制器的
代码在调用
createServer
的同一线程中运行


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

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

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


使用IDE确保您拥有所需的所有线程。使用调试器。挂起时暂停程序并检查所有线程。确保你至少有两个。(如果没有,这就是问题所在。)一个线程应该挂在套接字上。检查其他代码(如果存在)的挂起位置,并修复代码,使其不会挂起。

我刚刚发现问题-它在构造函数中:

/** 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();
}
/**服务器类构造函数*/
公用服务器(阻止队列){
eventQueue=队列;
试一试{
serverSocket=新的serverSocket(常量、端口号);
socket=serverSocket.accept();
inputStream=socket.getInputStream();
objectStream=新ObjectInputStream(inputStream);
}捕获(IOE异常){
e、 printStackTrace();
}  
螺纹=新螺纹(此);
thread.start();
}

带有
socket=serverSocket.accept()的行在创建单独的线程之前挂起了应用程序。我不知道为什么,但我在
run()
方法中查找了一个问题,这是错误的。

在大多数人回答之前,您必须发布一些简明的代码示例。我建议您添加更多的
println
调试或使用调试器来解决您的问题。谢谢,我已经发布了有问题的代码。我尝试过调试,但我的知识使我能够找到问题,但不幸的是无法解决问题。您是在为每个客户端启动一个线程,还是在一次读取一个客户端连接?是的,我应该编写它。游戏应该是p2p的——在开始时,玩家可以选择是要主持游戏还是连接到另一台服务器。每个服务器只允许一个客户端。请参阅createServer()和connectToServer()代码:好的,我知道-我只尝试过单向通信。确切地说,服务器中只有一个套接字,客户端中只有一个套接字-应用程序应该是p2p的。谢谢,没错,controller.run()是不必要的,但问题仍然存在。我在编写服务器代码时也这么认为,但应用程序仍然由于某种原因挂起。