当前位置: 首页 > 知识库问答 >
问题:

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

叶弘深
2023-03-14

我有一张地图。假设:

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

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

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

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

共有3个答案

云鸿达
2023-03-14

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

哈希图有一系列桶(列表);当您将数据放入 HashMap 时,哈希代码用于决定项目进入哪个存储桶,并将该项目添加到列表中。

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

梁丘德寿
2023-03-14

如果您确定每个线程只有一个条目,并且没有线程遍历/搜索映射,那么您为什么需要映射呢?

您可以改用 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

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

奚晟
2023-03-14

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

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

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

 类似资料:
  • 问题内容: 说我有一个全局对象: 有一个线程定期运行以从远程获取新编号并更新(仅写入): 并且有一个或多个线程随机使用此全局变量(仅读取): 您可以看到我不使用任何锁或对其进行保护,对吗?是否有可能引起问题的潜在问题? 更新: 就我而言,读取线程必须实时获取最新的值并不是很重要。我的意思是,如果有任何问题(由于缺少锁定/同步而导致)使一个读取线程错过了该值,那就没关系了,因为它将有机会尽快运行相同

  • 假设: 只有一个特定的线程设置了某个引用字段(不是长或双精度,所以写入它是原子的) 有任意数量的线程可能会读取同一个字段 稍微陈旧的读取是可以接受的(最多几秒钟) 在这种情况下,您需要挥发性或原子参考或类似的东西吗? 该条指出: 如果您严格遵守单一写入器原则,则不需要内存障碍。 这似乎表明,在我描述的情况下,你真的不需要做任何特殊的事情。 我做了一个测试,结果很奇怪: 有时运行this会输出“线程

  • 假设我有一组从客户机发送到服务器的请求ID。服务器的响应返回我发送的请求ID,然后我可以将其从哈希集中删除。这将以多线程的方式运行,因此多个线程可以在哈希集中添加和删除ID。然而,由于生成的ID是唯一的(从线程安全的源代码,比如现在的,它会针对每个新请求进行更新),是否需要是? 我认为这可能导致问题的唯一情况是遇到冲突,这可能需要对底层对象进行数据结构更改,但在这个用例中似乎不会发生这种情况。

  • 我用的是Netty camel-Netty:jar:2 . 10 . 0 . red hat-60024。下面是我对Netty监听器的配置 荨麻:tcp://10.1.33.204:9001?textline=true 在这里,我看到基于调试日志,Netty只创建一个工作线程,所以传入的消息被阻塞,直到现有的消息被处理。 喜欢: 2014-08-23 12:36:48,394|DEBUG|w I/

  • 考虑以下代码: 在一次采访中,我被问到了以下问题:如果只有一个线程调用,而多个线程可以调用,那么这个代码是线程安全的吗? 我知道,如果我们有多个写入线程,竞争条件可能会发生。然而,当每个读取线程中只有一个写入线程时,我们将按顺序获取值,即我们不会在之后读取,因为的写入发生在第一次读取,因此,在同一线程中的所有后续读取。这个推理是正确的,还是我漏掉了什么?

  • 问题内容: 我对同步块几乎没有疑问。 1. > 同步可确保您拥有一致的数据视图。这意味着您将读取最新值,而其他缓存将获得最新值。高速缓存足够智能,可以通过特殊总线相互通信(这不是JLS所必需的,但允许)。该总线意味着不必触摸主内存即可获得一致的视图。 如果仅使用同步,则不需要volatile。如果您有一个非常简单的操作(对于同步操作可能会过分杀伤),则波动性很有用。 参考上面,我有以下三个问题: