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

相關問題