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

Java 如果每个条目只有一个线程在访问它,那么映射是否需要同步?,java,multithreading,concurrency,Java,Multithreading,Concurrency,我有一张地图。让我们说: Map<String, Object> map = new HashMap<String, Object>(); Map Map=newhashmap(); 多个线程正在访问此映射,但是每个线程只访问映射中自己的条目。这意味着,如果线程T1将对象A插入到映射中,则可以保证没有其他线程访问对象A。最后,线程T1还将删除对象A 还可以保证没有线程在映射上迭代 此地图是否需要同步?如果是,您将如何同步它?(ConcurrentHashMap、Col

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

Map<String, Object> map = new HashMap<String, Object>();
Map Map=newhashmap();
多个线程正在访问此映射,但是每个线程只访问映射中自己的条目。这意味着,如果线程T1将对象A插入到映射中,则可以保证没有其他线程访问对象A。最后,线程T1还将删除对象A

还可以保证没有线程在映射上迭代


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

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

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


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

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

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


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

-首先,编写线程安全代码始终是一种实践,特别是在上述情况下,而不是在所有情况下


-最好使用
哈希表,它是一个
同步的
映射
,或者
java.util.concurrent.ConcurrentHashMap

-首先,编写
线程安全的代码始终是一种实践,特别是在上述情况下,而不是在所有情况下


-最好使用
HashTable
,它是一个
同步的
映射
,或者
java.util.concurrent.ConcurrentHashMap
您必须同步映射中的写入操作。如果初始化映射后,没有线程将插入新条目,或者删除映射中的条目,则不需要同步它

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


希望对您有所帮助

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

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


希望它有帮助

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

您可以改为使用
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
class-Foo{
字符串键;
目标价值;
....
}
//下面是你的地图声明
//地图=。。。
//请改用本地线程
final ThreadLocal threadLocalFoo=new ThreadLocal();
...
threadLocalFoo.set(新Foo(…);
threadLocalFoo.get()//返回您的对象
threadLocalFoo.remove()//清除threadLocal容器

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

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

您可以改为使用
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
class-Foo{
字符串键;
目标价值;
....
}
//下面是你的地图声明
//地图=。。。
//请改用本地线程
final ThreadLocal threadLocalFoo=new ThreadLocal();
...
threadLocalFoo.set(新Foo(…);
threadLocalFoo.get()//返回您的对象
threadLocalFoo.remove()//清除threadLocal容器

有关ThreadLocals的更多信息,请访问。

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

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


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

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

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


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

对于这种情况,我认为ConcurrentHashMap是最好的映射,因为这两个集合.synchronizedMap()或synchronized block(基本相同)都有更多的开销


如果您想插入条目,而不仅仅是在不同的线程中读取条目,那么由于HashMap的工作方式,您必须同步它们。

对于这种情况,我认为ConcurrentHashMa