2010-06-20 13 views
0

這是後續問題:Java. Serialization of objects in a multithreaded environmentJava。序列化高度不穩定對象集合的安全方法?

假設我有一個總是由多個線程執行的對象集合。

public class AlwaysChanging implements Serializable { 
    // ... state ... 

    public synchronized void updateFromThread1(int data) { /* ... */ } 
    public synchronized void updateFromThread2(int data) { /* ... */ } 

} 

什麼是序列化Collection<AlwaysChanging>的安全方法?

回答

2

首先,爲什麼你對不同的線程有不同的更新方法?這看起來雜亂無章。

要序列化集合,您需要確保您的AlwaysChanging在序列化期間沒有任何更改。從這個設計中,似乎唯一的方法就是在序列化之前保存所有的鎖。或者,您可以對整個集合進行深層複製(複製所有對象)並對其進行序列化。

在不瞭解應用程序的其他部分的情況下,我建議將ReadWriteLock視爲更細粒度的鎖定解決方案。

+0

如果訪問模式主要是寫入,那麼'ReadWriteLock'不會有太大的幫助,如此處所示。 – 2010-06-20 16:03:53

+0

有多個數據源通過一個接口從不同的線程推送數據(它們實際上並不叫'updateFromThreadX' :-)。每個AlwaysChanging對象都是這些數據源的訂閱者,並且可以一次處理多個線程。 「AlwaysChanging」本質上是事件驅動的;唯一的其他設計考慮可能是對輸入數據進行排隊(但這可能是不可能的,但這不能解決序列化問題)。 – Jake 2010-06-20 16:19:04

0

唯一安全的方法是在序列化時將集合設置爲只讀。

由於無法輕鬆地對所有對象(對某些同步的blockWhileSynchronizing()方法)執行方法調用,因此同步機制不起作用,因此請執行序列化。

將您的同步方法重寫爲在Executor中提交條目可能更容易,因爲這允許您控制實際執行的機制。

0

默認的同步方法是否足夠?由於你的更新方法是同步的,爲什麼不用同步重寫默認的序列化機制呢?

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { 
     lock(this) { 
     ois.defaultReadObject(); 
     } 
    } 

    private void writeObject(ObjectOutputStream oos) throws ClassNotFoundException, IOException { 
     lock(this) { 
     oos.defaultWriteObject(); 
     } 
    }