第一个线程是JMS订阅者,它监听主题。一旦收到消息,它就会在hashmap中添加/更新/删除条目。使用TimerClass每隔2分钟运行另一个线程,并读取相同散列映射的内容并将其存储在文件中并清除散列映射。请建议应该使用什么样的hashmap-并发或同步?有没有其他方法来实现这一目标?
答案 0 :(得分:2)
同步是必要的。
由于HashMap
未同步。
使用Collections.SynchronizedMap
或移至Hashtable
答案 1 :(得分:2)
你可以让第二个线程原子地用一个空的新的hashmap替换hashmap,等待一下并存储旧的数据。
为了使“等待”更精确,如果一条消息的处理时间没有明确的上限,则可以让第一个线程锁定地图,只要它正在使用它。然后第二个线程可以在写入内容之前获取锁定,这样就可以确保第一个线程完成了将最后一个消息的更改写入地图。
答案 2 :(得分:1)
最简单且可能最有效的解决方案是在同步块中使用常规HashMap。作者如下:
synchronized(mapLock)
{
map.put(...)
}
然后,清除线程可以简单地用新的空格替换地图:
Map oldMap;
synchronized(mapLock)
{
oldMap = map;
map = new HashMap<...>();
}
store(oldMap);
这将确保清洗螺纹尽可能短地保留在临界区域中。
目前我看不到在这种情况下使用ConcurrentHashMap的任何优势。如果要运行多个JMS线程,那可能会有所不同。
答案 3 :(得分:0)
如何简单地交换哈希映射?因此,线程2首先将线程1使用的hashmap设置为另一个,然后执行线程2所需的任何操作。这样您就不必处理序列化。 所以
storemap(){
mapcopy=thread1.map;
thread1.map=new Hashmap<Object>();
store(mapcopy);
}