2013-08-01 94 views
2

首先,我将描述我想要的内容,然后详细说明我正在考虑的可能性。我不知道哪个是最好的,所以我想要一些帮助。Hash Map的线程安全实现

我有一个散列图,我在Servlet上读取和写入操作。现在,由于这个Servlet在Tomcat上,我需要哈希映射是线程安全的。基本上,当它被写入时,没有其他东西应该写入它,也没有东西能够读取它。

我看过ConcurrentHashMap,但注意到它的get方法不是线程安全的。然后,我看到了锁和一些叫做synchronized的东西。

我想知道哪个是最可靠的方法。

+9

ConcurrentHashMap.get不是线程安全的方式?你在寻找什么级别的粒度?通过“当它被写入”时,你的意思是说将会有多个* put操作,还是每个人都是原子的就足够了? –

+0

看到API文档,我认为它不是线程安全的。如果说3个人决定进行相同的放置操作,那么对于哈希映射可以有多个放置操作。 – pratnala

+2

@pratnala事实上,它允许并发操作不会使它不是线程安全的。 – assylias

回答

3

编辑:删除虚假信息

在任何情况下,​​关键字是一个安全的赌注。它在​​块内阻止任何线程访问对象。

// Anything can modify map at this point, making it not thread safe 
map.get(0); 

,而不是

// Nothing can modify map until the synchronized block is complete 
synchronized(map) { 
    map.get(0); 
} 
+0

容器中每个“Servlet”只有一个实例。所有映射的请求都将通过同一个实例。如果您有实例字段,则每个请求都可以访问它们。 –

+0

尽管有一个servlet实例,但是请求在不同的线程中执行,即servlet的'service()'方法可以并发执行(除非Servlet被声明为'SingleThreadModel')。因此,可以从多个请求处理线程中调用在Servlet类中声明的实例变量。 –

+0

Ack。你(都)是对的,我不知道我在想什么。我认为我们(在工作中)通过一系列测试证明了这一点。我会删除我的答案的那部分。 – Deactivator2

3

Collections.synchronizedMap(new HashMap<K, V>);

返回由指定映射支持的同步(线程安全的)映射。为了保证串行访问,通过返回的映射完成对底图的所有访问是非常重要的。

当务之急是用户迭代它的任何集合视图时返回的地图上手动同步:

+0

你是什么意思?“通过返回的排序映射完成对支持排序映射的所有访问是非常重要的”? – pratnala

+0

错误地复制了Collection.synchronizedSortedMap()的描述,我的意思是说你传入的地图仍然不会是线程安全的 –

+0

我仍然不理解描述。 – pratnala

16

ConcurrentHashMap.get()是线程安全的。

你可以用Collections.synchronizedMap()包装HashMap线程安全。

+0

有什么区别? – naXa

+0

@naXa ConcurrentHashMap允许并发访问,并且'synchronized'不允许并发访问。 –

2

我想建议你去与ConcurrentHashMap,你所提到的要求,前面我也有过同样类型的需求为我们的应用程序,但我们更少关注性能方面。

我跑都ConcurrentHashMap和地图由Colecctions.synchronizedMap();返回,在不同类型的负载,并使用JMeter的同时发射多线程和我使用JProfiler的。毕竟这些测试,我们来到了结论,即通过地图返回Colecctions.synchronizedMap()监测他们并不像ConcurrentHashMap那样有效。

我写了一个post也对我的经验都一样。

谢谢

0

这是ConcurrentHashMap类的要点。它可以保护你的收藏品,当你有超过1个线程。