【问题标题】:How does setting concurrencyLevel in ConcurrentHashMap help if my hashCode() is weak?如果我的 hashCode() 很弱,在 ConcurrentHashMap 中设置 concurrencyLevel 有何帮助?
【发布时间】:2016-02-10 04:47:24
【问题描述】:

如果我声明ConcurrentHashMap<Person, Interests> - 如果我覆盖Person.hashCode() 以产生相同的哈希值[糟糕的设计你!],那么所有元素都放在同一个桶中 - 默认的 concurrencyLevel[16] 如何帮助并发写入?

我的理解是,在上述情况下,Map 条目没有分布。因此,在修改特定的 <K,V> 时,会在唯一存在的 hashBucket 上建立锁定,因此其他线程无法修改其他 <K1,V1> 并从并发修改中受益

【问题讨论】:

  • 在我看来,您的中心假设是无效的。 Javadoc 明确指出“concurrencyLevel 影响内部大小”。
  • 它如何影响内部尺寸?假设我的地图中有 100 个元素,并且都进入同一个桶。由于所有元素都属于同一段,因此只有一个线程可以修改 Map,其余的被阻塞。

标签: java multithreading collections concurrenthashmap


【解决方案1】:

在ConcurrentHashMap 中,写入操作只有在写入同一段时才能相互阻塞。也就是说,当您的 Person 对象具有相同的 hashCode() 结果时,它们都将被放置在 HashMap 的同一段中。

这意味着添加到ConcurrentHashMap 的内容将被同步,因为每次添加新的Person 对象时,都会获取ConcurrentHashMap 中单个LinkedList 的锁,并且其他线程试图添加另一个Person 需要等待。

【讨论】:

  • 我想知道细分和内部规模如何相关。如果有 100 个元素 - 均匀分布 [桶大小 1],我的 concurrencyLevel [16] 将如何划分为段 - 是 100/16,即每段大约 16 个元素?还是每个桶的分段?
  • concurrencyLevel 实际上指定了在给定时间有多少线程可以访问您的集合。如果您的并发级别为 16,并且您有 50 个线程尝试写入 50 个存储桶,则最多只有 16 个线程能够并行执行此操作。其他人将等待“插槽”。但是,如果所有 50 个线程都尝试访问单个存储桶,则只有一个会成功,其他线程将等待。 ConcurrencyLevel 应根据您希望访问集合的线程数进行设置。如果您期望 50 个线程,请将 ConcurrencyLevel 设置为 50。
猜你喜欢
  • 2012-08-25
  • 1970-01-01
  • 2011-03-22
  • 2015-12-21
  • 2011-10-26
  • 1970-01-01
  • 2011-05-02
  • 1970-01-01
  • 2021-07-18
相关资源
最近更新 更多