我有一张地图。让我们说:
Map<String, Object> map = new HashMap<String, Object>();
多个线程正在访问此映射,但每个线程仅访问映射中自己的条目。这意味着如果线程T1将对象A插入到映射中,则保证没有其他线程将访问对象A.最后,线程T1也将删除对象A.
也保证没有线程会遍历地图。
此地图是否需要同步?如果是,你会如何同步它? (ConcurrentHashMap,Collections.synchronizedMap()或synchronized块)
答案 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
synchronized
或Map
的{{1}}。
答案 3 :(得分:0)
您必须在地图中同步书写操作。如果在初始化地图后,没有线程要插入新条目,或者删除地图中的条目,则无需同步它。
但是,在你的情况下(每个线程都有自己的条目)我建议使用ThreadLocal,它允许你有一个“本地”对象,每个线程的值不同。
希望有所帮助
答案 4 :(得分:0)
我会说是的。获取数据不是问题,添加数据是。
HashMap
有一系列桶(列表);当您将数据放入HashMap
时,hashCode用于决定项目在哪个桶中,并且该项目将添加到列表中。
因此可能会同时将两个项目添加到同一个存储桶中,并且由于某些运行条件,其中只有一个被有效存储。
答案 5 :(得分:0)
对于这种情况,我认为ConcurrentHashMap是最好的Map,因为Collections.synchronizedMap()或synchronized块(基本相同)都有更多的开销。
如果你想插入条目而不仅仅是在不同的线程中读取它们,你必须同步它们,因为HashMap的工作方式。