在ConcurrentHashMap中如何定义段

你好朋友,我是Java并发新手。 我有两个问题如下。

Q.1在ConcurrentHashMap中如何定义段? 意味着如果在该Map中有64个元素,并且concurrencyLevel值为16(有16个线程可以同时工作),那么这些段如何定义? Q是他们相等大小的16个部分,每个部分有4个元素? 或者它会是不相等大小的细分市场?

Q.2。 如果我将初始容量定义为62,并发定义为16的ConcurrentHashMap。如果我在该地图中放置了62个元素。 根据我的理解,将会有15个分段,每个分段4个,第16个分段有2个分量? 我在这里纠正?

提前致谢


Q.1在ConcurrentHashMap中如何定义段? 意味着如果在该Map中有64个元素,并且concurrencyLevel值为16(有16个线程可以同时工作),那么这些段如何定义? Q是他们相等大小的16个部分,每个部分有4个元素? 或者它会是不相等大小的细分市场?

ANS - 如果将16定义为并发级别,则将创建16个段。

每个段内部维护HashTable S [0] - > HASHTABLE()。

因此,如果您有64个元素,那么对于每个元素,散列(Key)将计算段号,您可能拥有不等大小的所有段。 段哈希码的计算方式是它会在(0-15)之间返回任何数字。

Q.2。 如果我将初始容量定义为62,并发定义为16的ConcurrentHashMap。如果我在该地图中放置了62个元素。 根据我的理解,将会有15个分段,每个分段4个,第16个分段有2个分量? 我在这里纠正?

ANS-如上所述,每个段的选择都是基于计算出来的哈希码来完成的,因此不能确定所有16段都具有相同的大小。


考虑使用段的ConcurrentHashMap的实现(并非全部都是这样),因为它基本上是一个两级哈希表。 给定一个关键字K和密钥h = K.hashCode()哈希码,首先使用h对16个数据段进行哈希处理,就像正常的哈希映射一样(例如,通过采用h % 16或类似的东西)。 这为您提供了密钥所在的分段,这只是另一张地图 - 再次使用h查找此地图中的密钥。

不同之处在于,像put()这样的变化操作中通常会发生的任何锁定操作只需要锁定相关的段,以便其他操作有机会并行进行。

具体回答你的问题:

Q1

这些段的容量是相同的,但它们通常具有不同数量的元素,因为元素的段是使用散列来选择的,除非在不常见的情况下,这不会导致完全一致。 这与您询问在HashMap支持数组的前半部分是否具有与下半部分相同数量的元素相同。 平均而言,元素的期望数量是相同的,但对于任何给定的HashMap ,由于随机变化,两半中元素的数量完全相同。

Q2

不,地图不会像这样布置。 如上所述,使用散列完成元素到段的选择,这意味着(对于良好的散列函数)段基本上是随机选择的。 想象一下,你有一个标有1到16个球的球,并且你每次选择一个球62次,并在更换球之前记录下你得到的数字。 你不希望得到像4, 4, 4, 4, 4, 4, 4, 4, 4, ... , 4, 2, 2] ! 它会更随机。

链接地址: http://www.djcxy.com/p/91923.html

上一篇: In ConcurrentHashMap how the segments are defined

下一篇: how to lock free use two ConcurrentHashMap in java/scala?