Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/346.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';每次调用readObject时返回相同对象的对象流?_Java_Sockets_Serialization - Fatal编程技术网

为什么Java';每次调用readObject时返回相同对象的对象流?

为什么Java';每次调用readObject时返回相同对象的对象流?,java,sockets,serialization,Java,Sockets,Serialization,请原谅伪代码-我的无线网络已关闭,目前无法将代码从脱机计算机复制到StackExchange 我有两个java应用程序,通过java.net.*套接字连接。我试图通过objectinput/output流将“消息”对象从一个传递到另一个 以下是我正在做的: Class Message implements Serializable { String text int data public Message(String txt, int dat) { th

请原谅伪代码-我的无线网络已关闭,目前无法将代码从脱机计算机复制到StackExchange

我有两个java应用程序,通过java.net.*套接字连接。我试图通过objectinput/output流将“消息”对象从一个传递到另一个

以下是我正在做的:

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;
     }
}
服务器

for(int i = 0; i < 1000; i++)
{
  Message temp;
  temp = in.readObject()
  system.out.println(temp)
}
服务器有一个名为发件箱的队列

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)
 }
客户端

Hello 0
Hello 0
Hello 0
Hello 0...
因此,看起来消息对象正在被读取,但没有从流中删除


如何才能像预期的那样解除流的阻塞并使其同步?

此问题的典型原因是多次发送相同的对象引用。对象流将执行preserve Object reference identity,在接收端,每次readObject()调用都会返回相同的对象(即使您在发送端修改了对象!)。您的伪代码是正确的,但是问题是它是否准确地反映了您的实际代码


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

如果没有更完整的代码,很难说。。。如果将第一条消息更改为50或从0中突出的内容(可能只是一个“无”)会发生什么情况?@Robert It show
Hello 50
。第一次读取对象肯定是正确的。这是一个好迹象。但我不知道从这里该说什么。。。没有实际的代码,就不可能找到bug。你已经把你想写的东西写出来了,看起来是正确的,但是没有真正的复制/粘贴,就没有第二双眼睛来捕捉愚蠢的打字错误……你确定你每次都在通过真实代码中的循环来做
新的
消息,而不仅仅是重复使用消息,而是更改数据吗?@MeBigFatGuy我更新了这个问题。它现在正确地反映了我是如何加载消息的(尽管这样做会使伪代码看起来非常愚蠢),看起来它确实是一个引用问题!使用WriteUnshared()和Reset()有什么好处吗?更新了一些详细信息。显然,这些都在javadocs中。调用
writeUnshared
仍将共享原始对象引用的其他对象。对原始对象的嵌套回引用也不起作用
writeUnshared
不是很有用。但是,如果输入文件的数量(比如说,每行对应一个对象)达到或超过2 GB,则使用reset()会增加包含对象的输出文件的大小。如何避免这种情况。@user3552407-是的,它增加了输出的大小,因为它正在发送数据的新副本,而不仅仅是引用第一个副本。如果您想要共享引用,则不要调用
reset
。如果不希望共享引用,则需要执行一些操作,例如调用
reset
Hello 0
Hello 0
Hello 0
Hello 0...