为什么每次调用readObject时Java的Object Stream都返回相同的对象?

Rav*_*mer 11 java sockets serialization

原谅伪代码 - 我的无线网络已经关闭,我现在无法将代码从我的离线计算机复制到StackExchange.

我有两个java应用程序,通过java.net.*socket连接.我试图通过对象输入/输出流将"消息"对象从一个传递到另一个.

这是我正在做的事情:

Class Message implements Serializable
{
  String text
  int data
     public Message(String txt, int dat)
     {
      this.text = txt;
      this.data = dat;
     }
     string toString()
     {
      return text + " " + data;
     }
}
Run Code Online (Sandbox Code Playgroud)

服务器:

服务器有一个名为Outbox的队列

for(int i = 0; i < 1000; i++)
 { 

 Message adding = new Message("Hello!",i);
 Outbox.add(temp)
 Message temp =     Outbox.poll();
 out.writeObject(temp);
  system.out.println(temp)
 }
Run Code Online (Sandbox Code Playgroud)

客户:

for(int i = 0; i < 1000; i++)
{
  Message temp;
  temp = in.readObject()
  system.out.println(temp)
}
Run Code Online (Sandbox Code Playgroud)

现在我希望很明显,我希望每个程序的控制台看起来都一样.相反,这就是我要做的事情.

服务器

Hello 0
Hello 1
Hello 2
Hello 3...
Run Code Online (Sandbox Code Playgroud)

客户

Hello 0
Hello 0
Hello 0
Hello 0...
Run Code Online (Sandbox Code Playgroud)

因此,看起来消息对象正在被读取但不会从流中删除.

如何按预期方式疏通我的流并让它们同步?

jta*_*orn 21

这个问题的经典原因是多次发送相同的对象引用.对象流impls保留对象引用标识,并且在接收端,您将在每个readObject()调用上获得相同的对象(即使您已在发送方修改了对象!).你的伪代码是正确的,但问题是它是否准确反映了你的实际代码.

如果您的问题参考问题,您可以通过每次发送不同的对象实例,或在每次writeUnshared()调用reset()之间使用和/或调用来解决问题writeObject().using writeUnshared()将强制主对象成为接收端的新对象实例,但此对象可能引用的其他对象仍可能是共享引用.另一方面,调用reset()将刷新接收端的所有缓存对象,因此接收端的所有对象引用都将是新引用.哪一个更适合通过线路管理数据取决于您的使用情况,但是,对于长时间运行的流,定期调用总是好的reset(),因为这会释放随着时间的推移而积累的内存(这是常见的) ,但使用Object流时微妙的"内存泄漏").