2011-07-07 85 views
1

全部,其他線程修改對象時將對象寫入文件

我在寫一個多線程程序。擴展Thread的類有一個static Hashtalbe<Integer, SessionData> sessionDataTable

在這個類中,我會做一些改變sessionDataTable的事情,比如插入一個新的SessionData對象,從中刪除SessionData對象或修改Hashtable中的SessionData對象。

最後,我會寫的哈希表來使用ObjectOutputStream文件,方法是一樣的東西

public static synchronized void saveDataSessionState() 
{ 
    ... 
    ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Constants.logFile)); 
    oos.writeObject(sessionDataTable); 
    ... 
} 

我想知道如果一個線程是做oos.writeObject(sessionDataTable);但其他線程正在修改的sessionDataTable會發生什麼(就像我上面所說的),同時在這個方法之外的某個地方。將對象寫入文件時,上述方法是否會導致異常?

如果是,我怎麼能避免這個問題?使用鎖定?但是,當我修改Hashtable時,我需要鎖定它。

謝謝。

回答

3

基於我對代碼的考察,我認爲你不會有任何問題。 Hashtable類的訪問器和變體聲明爲​​,Hashtable上的私有writeObject方法聲明爲序列化。這應該足以確保在串行器正在查看時沒有任何東西可以改變Hashtable

但是,如果在序列化發生時某些東西改變了Hashtable鍵或值的狀態,則可能會遇到麻煩。 (我不知道是否執行了一個對象的默認序列化來保存一個對象的互斥體,我懷疑這並不是因爲不必要的鎖定的代價,一個簡單的互斥體不一定會達到所需的獨佔訪問的事實,以及潛在的風險的死鎖。)

+0

謝謝。你的評論幫了我很多。 – Jason

1

ConcurrentHashMap是你需要的。但是,這隻會解決哈希映射併發訪問問題。

與此同時,SessionData將需要做成不可變的,這將確保一個特定的實例一旦創建就永遠不會改變。如果需要修改哈希映射條目 - 只需將其替換爲SessionData的新實例即可。