简体   繁体   English

ConcurrentHashMap resizeStamp方法如何工作?

[英]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 of sc tells the information that there are at least one thread doing resizing operation on capcity n , 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 所以这个功能显然可以做两件事

  1. compute leading zero numbers of n as tmpReuslt 计算t的前零个n作为tmpReuslt
  2. make the 16th bit of 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. 执行成功。

  • And the higher 16 bit of 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM