1

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

任何更熟悉Java的人能够回答这个问题?我一开始不使用线程安全数据结构的原因是因为我的项目规范禁止使用它。谢谢!

4

3 回答 3

3

这应该没问题,因为地图实际上是只读的。您可能希望从使用Collections.unmodifiableMap或 Guava 的ImmutableMap.

但是,链接列表是另一回事,除非您可以保证对每个单独的列表进行单线程访问。如果没有,一个快速的解决方案是Collections.synchronizedList在创建时包装每个列表。或者你可以看看使用ConcurrentLinkedQueues 代替。

于 2013-04-30T01:03:20.413 回答
1

我一开始不使用线程安全数据结构的原因是因为我的项目规范禁止使用它。

呃……他们想要你做的是使用 Java 的低级同步原语实现你自己的同步。

这与对非同步数据结构执行非同步操作不同。


作为记录:

  • 如果您正在阅读/更新列表,则需要同步。
  • 即使是“有效不可变”的数据结构也需要安全地发布以避免潜在的内存危害。
  • 如果您在一个线程中创建数据结构并尝试在另一个线程中使用它,则会出现潜在问题……除非“创建”和“使用”操作之间存在发生前的关系。(如果父线程在调用start()子线程之前创建/初始化数据结构,那就足够了......)
于 2013-04-30T03:42:36.063 回答
0

修改任何数据都是不安全的,即使是在没有同步的情况下同时修改单个布尔字段也是如此。“Java 并发实践”中的黄金法则:当多个线程访问给定状态变量时,其中一个可能会写入,它们都必须使用同步来协调对它的访问。

于 2013-04-30T03:25:55.090 回答