2012-04-11 58 views
0

我有一些通过RMI序列化并发访问的对象。最近我写了自定义的序列化方法:我是否需要同步writeObject()?

/** This method is made to omit serialization of this.order */ 
private void writeObject(java.io.ObjectOutputStream out) 
    throws java.io.IOException 
{ 
    Order tmpOrder = this.order; 
    this.order = null; 
    out.defaultWriteObject(); 
    this.order = tmpOrder; 
} 

private void readObject(java.io.ObjectInputStream in) 
    throws java.io.IOException, ClassNotFoundException 
{ 
    in.defaultReadObject(); 
} 

我不想允许通过并发RMI线程破坏this.order。

  1. 是否需要使writeObject同步?或
  2. RMI框架是否尽最大努力同步访问对象?

在第二种情况下,我的同步甚至可能导致RMI中的死锁。 JAVA API的一般契约是一个方法被一个线程调用,除非特别注明。所以如果我遵循规则,我应该离开writeObject而不进行任何同步。它是否正确 ?

我的问题的另一个解决方案,而没有回答这个问题肯定宣布private static final ObjectStreamField[] serialPersistentFields。 (我不能让现场瞬时因为对象不仅是DTO而是一个JPA实体也)

回答

2

我有一个由RMI 系列化

并发访问某些对象不,你不。您有一些对象可以通过对象序列化并发访问

RMI框架是否尽最大努力同步访问对象?

不可以。对象序列化框架可能但没有指定。

+0

感谢您给我更多关于JAVA序列化API的详细信息:-)。所以我可以看到我在上面的代码snipset中没有什么可担心的。 ;-) – 2012-04-11 09:57:48

+1

@digital_infinity你是否考虑过使用'order'瞬态,并且抛弃你的'readObject()'和'writeObject()'方法? – EJP 2012-04-11 10:06:50

+0

是的,这就是为什么我写了我的问题的最后一段;-)。该对象由Hibernate使用,并且不能是暂时的(java关键字)。 – 2012-04-11 10:20:58

1

试图序列化并发使用的对象将导致混乱。当然,要阅读一致的状态,甚至是一个良好的状态,你通常需要独占锁定。如果writeObject是同步的,那么你有极端的问题,确保锁定顺序表现良好。

添加serialPersistentFields(拼写正确:)应该与制作字段transient具有相同的行为。制作ordertransient将停止它被写出,这似乎是你正在尝试在问题代码。使用ObjectOutputStream.putFields也可以实现类似的功能。

+0

实际上,除了序列化之外,我还自己同步对象。当对象将被序列化时,它们不再被改变。 在某些情况下,不同的对象通过不同的线程客户端RMI调用(同时是几个RMI服务器的RMI客户端)同时发送给少数收件人。这就是为什么我在序列化时对同步问题有些怀疑。 – 2012-04-11 11:20:52

+0

@digital_infinity所以如果你的'writeObject'改变了这个对象,并且你可能有多个线程在同一个对象上调用了这个方法,那么这将需要一些锁定来处理所有的问题。 (另外,正如所写,它不是例外 - 安全。) – 2012-04-11 11:46:34

+0

所以你告诉我,EJP的答案是不正确的?对象序列化是进行同步的魔术盒。我无法在这里同步,因为我的同步将干扰对象序列化的同步并可能导致死锁。想象一下序列化我的对象的数组。 – 2012-04-11 11:58:04

相关问题