两个线程访问相同的hashmap,一个线程在2分钟后连续运行其他运行并清除该hashmap,如何在java中处理这个

时间:2013-12-13 12:05:05

标签: java multithreading timer timertask

第一个线程是JMS订阅者,它监听主题。一旦收到消息,它就会在hashmap中添加/更新/删除条目。使用TimerClass每隔2分钟运行另一个线程,并读取相同散列映射的内容并将其存储在文件中并清除散列映射。请建议应该使用什么样的hashmap-并发或同步?有没有其他方法来实现这一目标?

4 个答案:

答案 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);
}