并发修改HashMap的表项是否安全?如果映射的大小是固定的,并且条目是链表



我目前有一个固定大小的链表HashMap,我想知道是否可以通过调用get()修改两个不同键的值,然后修改该链表的内容(添加/减去节点和东西)?我知道同时修改不同的键是不安全的,因为可能会调整大小的问题,但是1)hashmap的大小是固定的,链表从一开始就被初始化(作为空列表),2)我怀疑在这样的情况下,hashmap会存储指向链表的指针,因此修改列表实际上不会修改hashmap的内容,但我不能确定。

有更熟悉Java的人能回答这个问题吗?我没有使用线程安全数据结构的原因是我的项目规范禁止使用它。谢谢!

这应该没问题,因为映射实际上是只读的。您可能希望在初始化时使用Collections.unmodifiableMap或Guava的ImmutableMap来强制执行此操作。

链表是另一回事,除非你能保证单线程访问每个单独的列表。如果没有,一个快速的解决方案是在创建时使用Collections.synchronizedList包装每个列表。或者您可以考虑使用ConcurrentLinkedQueue s。

我没有使用线程安全的数据结构的原因是,这是我的项目规范所禁止的。

这里好吃……他们想让你做的是使用Java的低级同步原语实现你自己的同步。

这和在不同步的数据结构上做不同步的操作是不一样的。


记录:

  • 如果您正在读取/更新列表,则需要同步。
  • 即使是"有效不可变"的数据结构也需要安全发布,以避免潜在的内存危害。
  • 如果你在一个线程中创建了一个数据结构,并试图在另一个线程中使用它,有一个潜在的问题…除非在"创建"one_answers"使用"动作之间存在happens-before关系。(如果父线程在子线程上调用start()之前创建/初始化了数据结构,那就足够了…)

在没有同步的情况下并发修改任何数据都是不安全的,即使是单个布尔字段。

>

最新更新