0

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

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

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

还保证没有线程会遍历映射。

这个地图需要同步吗?如果是,您将如何同步它?(ConcurrentHashMap、Collections.synchronizedMap() 或同步块)

4

6 回答 6

4

是的,您需要同步或并发映射。想想映射的大小:两个线程可以并行添加一个元素,并且都增加大小。如果您不同步地图,您可能会遇到争用情况,这会导致大小不正确。还有许多其他可能出错的事情。

但是您也可以为每个线程使用不同的映射,不是吗?

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

于 2012-11-23T10:18:25.237 回答
2

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

您可以使用ThreadLocalobject 代替,它将包含特定于线程的数据。如果您需要保留字符串-对象对,您可以为该对创建一个特殊类,并将其保留在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

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

于 2012-11-23T10:22:09.870 回答
0

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

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

于 2012-11-23T10:28:37.183 回答
0

-首先,编写 a 始终是一种习惯Thread-safe code,特别是在上述情况下,而不是在所有情况下。

-好吧,最好使用HashTablewhich is a synchronized Map, or java.util.concurrent.ConcurrentHashMap<K,V>

于 2012-11-23T10:18:58.453 回答
0

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

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

希望能帮助到你

于 2012-11-23T10:19:45.503 回答
0

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

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

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

于 2012-11-23T10:24:34.850 回答