[英]How does ConcurrentHashMap resizeStamp method work?
In the source code of ConcurrentHashMap
, there is a method called resizeStamp
, the code is: 在
ConcurrentHashMap
的源代码中,有一个名为resizeStamp
的方法,代码为:
static final int resizeStamp(int n) {
return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
}
How does this code work? 此代码如何工作?
Short Answer: take
sc
as the result of(resizeStamp(n) << RESIZE_STAMP_SHIFT)
, the higher 16 bit ofsc
tells the information that there are at least one thread doing resizing operation on capcityn
, the lower 16 bit tells the information that how many theards are doing this resizing concurrently.答案很简单:取
sc
作为的结果(resizeStamp(n) << RESIZE_STAMP_SHIFT)
较高的16位sc
告诉信息至少有一个线程执行上capcity调整操作n
,低16位告诉信息有多少先行者正在同时调整大小。
Explaination: 说明:
First, checkout the documentation of resizeStamp(n)
首先,
resizeStamp(n)
的文档
/**
* Returns the stamp bits for resizing a table of size n.
* Must be negative when shifted left by RESIZE_STAMP_SHIFT.
*/
static final int resizeStamp(int n) {
return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
}
so this function clearly do two things 所以这个功能显然可以做两件事
tmpReuslt
tmpReuslt
tmpResult
be 1 ( Notice: RESIZE_STAMP_BITS
is a constant which equals 16 ) tmpResult
第16位tmpResult
为1(注意: RESIZE_STAMP_BITS
是等于16的常量) so resizeStamp return a 32-bit int value which has format 0000 0000 0000 0000 1xxx xxx xxxx xxxx
所以resizeStamp返回一个32位int值,其格式为
0000 0000 0000 0000 1xxx xxx xxxx xxxx
as the documentation says, the return result " Must be negative when shifted left by RESIZE_STAMP_SHIFT" . 如文档所述,返回结果“当向左移动RESIZE_STAMP_SHIFT时必须为负”。
Obviously, when the 16th bit is set to 1, when shifted left by RESIZE_STAMP_SHIFT , the highest bit of the reuslt would be 1, which make it a negative number. 显然,当第16位设置为1时,向左移动RESIZE_STAMP_SHIFT时,重用的最高位将为1,这使其成为负数。
Then, the second question comes, why does it do this, checkout the addCount(long x, int check)
function in ConcurrentHashMap 然后,第二个问题来了,为什么要这样做,在ConcurrentHashMap中检出
addCount(long x, int check)
函数
// some code here
if (check >= 0) {
Node<K,V>[] tab, nt; int n, sc;
while (s >= (long)(sc = sizeCtl) && (tab = table) != null &&
(n = tab.length) < MAXIMUM_CAPACITY) {
int rs = resizeStamp(n);
if (sc < 0) {
if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
sc == rs + MAX_RESIZERS || (nt = nextTable) == null ||
transferIndex <= 0)
break;
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSwapInt(this, SIZECTL, sc,
(rs << RESIZE_STAMP_SHIFT) + 2))
transfer(tab, null);
s = sumCount();
}
}
resizeStamp is used to assgin value of sizeCtl in ConcurrentHashMap, by operation (rs << RESIZE_STAMP_SHIFT) + 2
. resizeStamp用于通过操作
(rs << RESIZE_STAMP_SHIFT) + 2
来在ConcurrentHashMap中提升sizeCtl的值。
resizeStamp function ensures sizeCtl
gets a negative value if resizeStamp函数可确保在以下情况下
sizeCtl
获得负值
U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2)
executed successfully. 执行成功。
sizeCtl
can tell the information : on which size n
, the resizing operation is going on sizeCtl
的高16位可以告诉信息:在大小为n
,正在进行大小调整操作
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.