Java:序列化第二次不起作用

时间:2011-01-04 18:53:32

标签: java serialization garbage-collection

我有一台服务器,我可以跟踪一些数据。当我使用管理员应用程序连接到服务器时检查数据的当前状态。我使用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;
}

我尝试的是在从流中读取Object之前调用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没有刷新。 然后我通过用数组替换List来解决它有点棘手:

public static class MonitorResponse implements Serializable
{
    public int numberOfLLN;
    public int blocked;
    public int blancos;
    public Integer[] votes;
}

这很完美。如果你问我,很奇怪。我改变了代码的另一部分......(除了实现数组而不是List)

1 个答案:

答案 0 :(得分:5)

可能导致问题的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.
    }
}