【问题标题】:Is Java (de-)serialization atomic?Java(反)序列化是原子的吗?
【发布时间】:2016-02-22 08:17:19
【问题描述】:

对于这个问题,假设当对象完全写入流并成功读出时,序列化/反序列化是原子的,或者当对象部分写入流并且读回对象时发生异常。假设写操作可能无法成功完成,例如因为停电。

Serializable 类的描述中,我读到:

如果序列化流已被篡改,也可能发生这种情况;因此,readObjectNoData 对于正确初始化反序列化对象很有用,尽管源流存在“敌意”或不完整。

可能暗示从ObjectInputStream 读取对象不是原子的。这是否意味着从流中读取 Java 对象可能不是原子操作?

如果部分对象被写入持久内存然后被检索,我确定会引发异常吗?

如果 Java 序列化是非原子的,是否有任何将对象(反)序列化到持久内存作为原子操作的最佳实践?


注意事项:

  • 这里我不考虑序列化到数据库(例如使用 Hibernate);对于持久存储,我的意思是例如使用ObjectInputStreamFileInputStream
  • 对于原子,我的意思是例如在对象写入磁盘时发生断电后读取对象期间发生的情况;
  • 我没有使用多线程从流中读取或写入对象。

【问题讨论】:

    标签: java serialization persistence atomic objectinputstream


    【解决方案1】:

    这可能暗示从 ObjectInputStream 读取对象不是原子的。这是否意味着从流中读取 Java 对象可能不是原子操作?

    我不知道任何地方的任何陈述 在你的意思上是原子的,但我也看不出它与你引用的摘录有什么关系。读取一个对象涉及相当多的读取操作:标签、类名和所有字段,因此整个操作不可能是您所说的意义上的原子。

    如果部分对象被写入持久内存然后被检索,我确定会引发异常吗?

    我不明白如何避免出现异常。

    如果 Java 序列化是非原子的,是否有将对象序列化到持久内存作为原子操作的最佳实践?

    您无法确保它发生,但您可以捕获如果没有发生则引发的异常。调用flush(),如果失败则表示序列化不完整。

    我的意思是例如在写入磁盘时断电期间会发生什么

    将对象写入磁盘也不是原子的。它们由几个逻辑写入组成。如果你的程序因为停电而停止,甚至没有得到IOException,那么你只有一个短文件,读取时会导致异常。

    【讨论】:

    • 好的,所以如果部分对象编码丢失,肯定会有例外,在这种情况下?我认为运动自定义编码/数组的对象可能不是这种情况?
    • 等一下,我太傻了。如果它不知道数据何时结束,它就无法区分一个对象和另一个对象。所以对象的格式必须包含一个明确定义的结尾。
    • 协议中有长度词,标签上写着'这是一个int,等等。
    猜你喜欢
    • 1970-01-01
    • 2014-07-16
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2011-07-09
    相关资源
    最近更新 更多