假设我有一个类ServerReader,它是一直运行的Thread。 ServerReader有一个循环,它以这样的方式读取来自所有客户端的所有消息:
while(true) {
for(Socket socket: sockets_arraylist) {
ObjectInputStream object_stream = new ObjectInputStream(socket.getInputStream());
String str = (String) object_stream.readObject();
System.out.println("message from client: " + str);
object_stream.close();
}
}
据我所知,当循环遇到readObject()方法时,Thread将进入休眠状态,直到客户端实际发送一个对象。 想象一下这个场景: ArrayList“sockets_arraylist”包含2个套接字。列表中的第二个套接字,属于客户端号2等待接收消息。客户端号码2发送此消息并等待服务器读取它。但是有一个问题:上面的循环停留在等待来自客户端1的消息的readObject()方法。因此,直到客户端1不会将其消息发送到服务器,客户端的2消息将不会被读取。
我是否需要在服务器上为每个客户端创建一个separete线程?还是有另一种解决方案?
答案 0 :(得分:4)
有两种解决方案:
1)为每个客户使用单独的线程。
2)使用java.nio
使用异步IO - 在这种情况下,您可能需要SocketChannel
。
为每个客户端使用单独的线程可能在概念上更简单,但它确实意味着您需要更仔细地考虑竞争条件。使用NIO 可能可扩展性更高(不同的基准测试显示不同的结果,并且在线程和调度的成本方面也很可能取决于您的操作系统。)