如果每个条目只有一个线程正在访问它,那么map是否需要同步?

时间:2012-11-23 10:13:41

标签: java multithreading concurrency

我有一张地图。让我们说:

Map<String, Object> map = new HashMap<String, Object>();

多个线程正在访问此映射,但每个线程仅访问映射中自己的条目。这意味着如果线程T1将对象A插入到映射中,则保证没有其他线程将访问对象A.最后,线程T1也将删除对象A.

也保证没有线程会遍历地图。

此地图是否需要同步?如果是,你会如何同步它? (ConcurrentHashMap,Collections.synchronizedMap()或synchronized块)

6 个答案:

答案 0 :(得分:4)

是的,您需要同步或并发映射。只要考虑一下地图的大小:两个线程可以并行添加一个元素,并且都会增加大小。如果不同步地图,则可能会出现竞争条件,从而导致大小不正确。还有很多其他问题可能会出错。

但你也可以为每个帖子使用不同的地图,不是吗?

ConcurrentHashMap通常比同步HashMap更快。但选择取决于您的要求。

答案 1 :(得分:2)

如果您确定每个线程只有一个条目且没有线程迭代/搜索地图,那么为什么需要地图?

您可以使用ThreadLocal对象,而不包含特定于线程的数据。如果需要保留字符串 - 对象对,可以为该对创建一个特殊类,并将其保留在ThreadLocal字段中。

class Foo {
   String key;
   Object value;
   ....
}

//below was your Map declaration
//Map<String, Object> map = ...
//Use here ThreadLocal instead
final ThreadLocal<Foo> threadLocalFoo = new ThreadLocal<Foo>();
...
threadLocalFoo.set(new Foo(...));
threadLocalFoo.get() //returns your object
threadLocalFoo.remove() //clears threadLocal container

您可以在ThreadLocal javadocs找到有关ThreadLocals的更多信息。

答案 2 :(得分:0)

- 首先,它总是一种写Thread-safe code的做法,特别是在上述情况下,并非在所有条件下。

- 最好使用HashTable synchronizedMap的{​​{1}}。

答案 3 :(得分:0)

您必须在地图中同步书写操作。如果在初始化地图后,没有线程要插入新条目,或者删除地图中的条目,则无需同步它。

但是,在你的情况下(每个线程都有自己的条目)我建议使用ThreadLocal,它允许你有一个“本地”对象,每个线程的值不同。

希望有所帮助

答案 4 :(得分:0)

我会说是的。获取数据不是问题,添加数据是。

HashMap有一系列桶(列表);当您将数据放入HashMap时,hashCode用于决定项目在哪个桶中,并且该项目将添加到列表中。

因此可能会同时将两个项目添加到同一个存储桶中,并且由于某些运行条件,其中只有一个被有效存储。

答案 5 :(得分:0)

对于这种情况,我认为ConcurrentHashMap是最好的Map,因为Collections.synchronizedMap()或synchronized块(基本相同)都有更多的开销。

如果你想插入条目而不仅仅是在不同的线程中读取它们,你必须同步它们,因为HashMap的工作方式。