我有一个服务器,我在上面跟踪一些数据。当我使用管理员应用程序连接到服务器以检查数据的当前状态时。我使用 5 秒的刷新率。服务器第一次发送数据时,它工作。但是第二次,当数据发生变化时,管理端没有收到最新的数据。我正在通过 ObjectOutputStream 和 ObjectInputStream 发送包装在一个类中的数据:
这是数据的包装类:
public class Leerling implements Serializable {
public int llnID;
public String naam;
public String voornaam;
public String klas;
public int klasNummer;
public Date geboorteDatum;
public String getFullName()
{
return voornaam + " " + naam;
}
@Override
public String toString() {
return "Leerling{" + "llnID=" + llnID + ", naam=" + naam + ", voornaam=" + voornaam + ", klas=" + klas + ", klasNummer=" + klasNummer + ", geboorteDatum=" + geboorteDatum + '}';
}
}
public class SLeerling extends Leerling implements Serializable{
public boolean voted;
public int vote = -2;
}
我尝试的是在从流中读取对象之前调用 System.gc();
确保对象旧对象不再在内存中。但没有成功。
有人知道确切的问题是什么吗?以及如何才能获得真正的最新数据?
提前致谢。
问题的第二个例子:
我又有了一些其他数据的包装类(它是一个内部类):
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public List<Integer> votes;
}
当我第一次发送数据时,它起作用了。但是我第二次发送它(更新它),除了 List<Integer> votes
之外的所有内容已更新。所以votes
没有刷新。
然后我通过用数组替换列表来解决它有点棘手:
public static class MonitorResponse implements Serializable
{
public int numberOfLLN;
public int blocked;
public int blancos;
public Integer[] votes;
}
这很完美。如果你问我很奇怪。代码的另一部分我几乎没有改变......(除了实现数组而不是列表)
最佳答案
可能是 ObjectOutputStream
导致了问题。
如果您在服务器上使用单个 ObjectOutputStream
对象,那么您需要确保对其调用 reset
,否则它会将共享引用写入先前编写的对象.这听起来像您所看到的。
为了说明问题:
class BrokenServer {
void sendBrokenVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.writeObject(votes); // Writes a shared reference to "votes" WITHOUT updating any data.
}
}
class FixedServer {
void sendFixedVoteData(ObjectOutputStream out) {
out.writeObject(votes);
changeVoteData(votes);
out.reset(); // Clears all shared references.
out.writeObject(votes); // Writes a new copy of "votes" with the new data.
}
}
关于Java:序列化第二次不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4597232/