Servlet中的ConcurrentHashMap

时间:2012-08-02 13:33:34

标签: java concurrency

我存储在servlet上下文中的ConcurrentHashMap,地图中的数据同时更改,我知道servlet上下文不是线程安全的,但ConcurrentHashMap是(用于写入)。在这种情况下我应该使用同步构造吗?

 synchronized (context) {
   ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map");
   String mes  = messages.get("id");  // can be changed by another thread?
   messages.put("id",mes +"changed by thread 1");   
  }

3 个答案:

答案 0 :(得分:1)

如果你在ServletContext inits时存储Map,那么你不需要同步获取它,因为在上下文关闭之前你不会删除它。

如果Map处理并发性并不重要。在后一种情况下,您需要在Map上进行同步,但是当您使用处理并发的时,您甚至不需要这样做。

答案 1 :(得分:1)

抱歉,我没有看到问题。在这个例子中,“messages”是一个局部变量,每个线程都有一个。你没有分享“消息”

当您从“上下文”中读取时,可能会出现唯一的问题,因此,您只需要同步该读取

ConcurrentHashMap messages = null;
synchronized (context) {
    ConcurrentHashMap messages =(ConcurrentHashMap)context.getAttribute("map");
}
String mes  = messages.get("id");  // can be changed by another thread?
messages.put("id",mes +"changed by thread 1");   

但是,最好的办法是避免这种情况。如何避免在读取表单上下文中同步?很简单,你不能写上下文或只在初始化过程中这样做。

答案 2 :(得分:0)

如果您担心在持有对它的引用后在Map上进行了更改,您可以做的是通过返回Map副本的方法来包装代码。在这种情况下,您将从复制时间保存地图的快照。

如果要完全同步更改,可以使用Collections.syncrhonizedMap(...)