所有
我正在写一个多线程程序。扩展Thread的类有static Hashtalbe<Integer, SessionData> sessionDataTable
。
在类中,我将做一些事情来更改sessionDataTable,比如在其中插入一个新的SessionData对象,从中删除SessionData对象或修改Hashtable中的SessionData对象。
最后,我将使用ObjectOutputStream将Hashtable写入文件,该方法类似于
public static synchronized void saveDataSessionState()
{
...
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Constants.logFile));
oos.writeObject(sessionDataTable);
...
}
我想知道如果一个线程正在执行oos.writeObject(sessionDataTable);
会发生什么,但是其他线程正在修改sessionDataTable(就像我上面所说的那样)同时在这个方法之外的某个地方。将对象写入文件时,上述方法是否会导致异常?
如果是,我怎么能避免这个问题呢?用锁?但是每当我修改Hashtable时我都需要锁定。
感谢。
答案 0 :(得分:3)
根据我对代码的检查,我认为你不会有任何问题。 Hashtable
类的访问器和更改器声明为synchronized
,writeObject
上的私有Hashtable
方法也进行了序列化。这应该足以确保在序列化程序查看它时没有任何内容可以更改Hashtable
。
但是,如果在序列化发生时某些内容更改了Hashtable
键或值的状态,则可能会遇到麻烦。 (我不知道是否使用对象的互斥锁执行对象的默认序列化。我怀疑不是因为不必要的锁定成本,简单的互斥锁不一定能实现所需的独占访问,以及潜在的风险死锁。)
答案 1 :(得分:1)
ConcurrentHashMap就是您所需要的。但是,这只能解决哈希映射并发访问问题。
同时,SessionData需要变为不可变,这将确保特定实例在创建后永远不会更改。如果需要修改哈希映射条目 - 只需将其替换为SessionData的新实例。