Java ObjectInputStream:如何检查新数据?

时间:2014-01-24 02:51:16

标签: java io objectinputstream

我正在使用Java和ObjectInputStream以及ObjectOutputStream来编写TCP客户端/服务器对。服务器通过ObjectOutputStream发送数据,客户端接收ObjectInputStream中的数据。

部分客户端代码如下:

try {
    newMessage = (Message) in.readObject();
    System.out.println(newMessage);

} catch (Exception e) { // temporary
    System.out.println(e);
}

不幸的是readObject()是一种阻止方法,这意味着如果ObjectInputStream中没有新的对象,它只会等到一个到达。

(注意:与readInt()不同,readObject()在达到EOF时不会抛出EOFException。)

这是一个问题:这可能是在一个单独的线程中,但我不希望线程在等待新消息到达时挂起。我宁愿使用Timer来安排定期检查ObjectInputStream

如何检查ObjectInputStream中是否有新数据,以便在没有新数据时我可以避免调用readObject()

3 个答案:

答案 0 :(得分:2)

正确的实施是阻止。尝试确定是否有足够的可用数据将无法可靠地工作,因为您甚至不知道需要查找多少字节。 Streams通常也不知道有多少数据可用,因为这取决于操作系统处理网络堆栈和其他参数的某处。

java.nio包中阻塞流的非阻塞替代方案可以处理单个线程中的多个连接,但这是一个完全不同的故事。

答案 1 :(得分:0)

写入端可以通过ByteArrayOutputStream将对象写入字节数组。然后它发送长度(int)然后发送字节arrray。接收方读取长度,然后将字节读入字节数组,然后通过ByteArrayInputStream从字节数组中读取对象

答案 2 :(得分:0)

我的建议是使用Netty等NIO框架来解决这个问题。 Netty是基于事件的。当NIO线程(由Netty本身管理)解码传入消息时,您将收到相应的事件。然后,您可以将消息发送到您自己的工作线程并进行处理。

或者,如果您不想涉及第三方依赖项,只需使用两个线程来解决此问题。一个线程在readObject()上循环并阻塞,一旦获得传入消息,它就会将消息放入队列,例如java.util.concurrent.LinkedBlockingQueue。另一个线程计划使用LinkedBlockingQueue.peek()方法以某种速率检查队列。如果peek返回了某些内容,只需将poll从队列中取出并处理它。如果没有,线程将不会被阻止,因此它可能会被阻止。