Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么ConcurrentHashMap没有';t使用';CAS&x27;但是使用';同步';当tabAt[i]不为空时 final V putVal(K键,V值,仅布尔值){ 如果(key==null | | value==null)抛出新的NullPointerException(); int hash=spread(key.hashCode()); int binCount=0; 对于(节点[]选项卡=表;;){ 节点f;int n,i,fh; 如果(tab==null | |(n=tab.length)==0) tab=initTable(); else if((f=tabAt(tab,i=(n-1)&散列))==null){ 如果(casTabAt,i,空, 新节点(哈希、键、值、null))) break;//添加到空箱子时没有锁 } else if((fh=f.hash)==MOVED) tab=帮助转移(tab,f); 否则{ V oldVal=null; 已同步(f){ if(tabAt(tab,i)==f){ 如果(fh>=0){ binCount=1; 对于(节点e=f;;++binCount){ 凯克; 如果(e.hash==hash&& ((ek=e.key)=key|| (ek!=null&&key.equals(ek))){ oldVal=e.val; 如果(!onlyFabSent) e、 val=值; 打破 } 节点pred=e; 如果((e=e.next)==null){ pred.next=新节点(散列、键、, 值,空); 打破 } } } else if(树的f实例){ 节点p; binCount=2; if((p=((TreeBin)f).putTreeVal(散列,键, 值)!=null){ oldVal=p.val; 如果(!onlyFabSent) p、 val=值; } } } } if(binCount!=0){ 如果(binCount>=树型\u阈值) treeifyBin(表一); 如果(oldVal!=null) 返回oldVal; 打破 } } } 添加计数(1L,二进制计数); 返回null;_Java_Concurrenthashmap - Fatal编程技术网

Java 为什么ConcurrentHashMap没有';t使用';CAS&x27;但是使用';同步';当tabAt[i]不为空时 final V putVal(K键,V值,仅布尔值){ 如果(key==null | | value==null)抛出新的NullPointerException(); int hash=spread(key.hashCode()); int binCount=0; 对于(节点[]选项卡=表;;){ 节点f;int n,i,fh; 如果(tab==null | |(n=tab.length)==0) tab=initTable(); else if((f=tabAt(tab,i=(n-1)&散列))==null){ 如果(casTabAt,i,空, 新节点(哈希、键、值、null))) break;//添加到空箱子时没有锁 } else if((fh=f.hash)==MOVED) tab=帮助转移(tab,f); 否则{ V oldVal=null; 已同步(f){ if(tabAt(tab,i)==f){ 如果(fh>=0){ binCount=1; 对于(节点e=f;;++binCount){ 凯克; 如果(e.hash==hash&& ((ek=e.key)=key|| (ek!=null&&key.equals(ek))){ oldVal=e.val; 如果(!onlyFabSent) e、 val=值; 打破 } 节点pred=e; 如果((e=e.next)==null){ pred.next=新节点(散列、键、, 值,空); 打破 } } } else if(树的f实例){ 节点p; binCount=2; if((p=((TreeBin)f).putTreeVal(散列,键, 值)!=null){ oldVal=p.val; 如果(!onlyFabSent) p、 val=值; } } } } if(binCount!=0){ 如果(binCount>=树型\u阈值) treeifyBin(表一); 如果(oldVal!=null) 返回oldVal; 打破 } } } 添加计数(1L,二进制计数); 返回null;

Java 为什么ConcurrentHashMap没有';t使用';CAS&x27;但是使用';同步';当tabAt[i]不为空时 final V putVal(K键,V值,仅布尔值){ 如果(key==null | | value==null)抛出新的NullPointerException(); int hash=spread(key.hashCode()); int binCount=0; 对于(节点[]选项卡=表;;){ 节点f;int n,i,fh; 如果(tab==null | |(n=tab.length)==0) tab=initTable(); else if((f=tabAt(tab,i=(n-1)&散列))==null){ 如果(casTabAt,i,空, 新节点(哈希、键、值、null))) break;//添加到空箱子时没有锁 } else if((fh=f.hash)==MOVED) tab=帮助转移(tab,f); 否则{ V oldVal=null; 已同步(f){ if(tabAt(tab,i)==f){ 如果(fh>=0){ binCount=1; 对于(节点e=f;;++binCount){ 凯克; 如果(e.hash==hash&& ((ek=e.key)=key|| (ek!=null&&key.equals(ek))){ oldVal=e.val; 如果(!onlyFabSent) e、 val=值; 打破 } 节点pred=e; 如果((e=e.next)==null){ pred.next=新节点(散列、键、, 值,空); 打破 } } } else if(树的f实例){ 节点p; binCount=2; if((p=((TreeBin)f).putTreeVal(散列,键, 值)!=null){ oldVal=p.val; 如果(!onlyFabSent) p、 val=值; } } } } if(binCount!=0){ 如果(binCount>=树型\u阈值) treeifyBin(表一); 如果(oldVal!=null) 返回oldVal; 打破 } } } 添加计数(1L,二进制计数); 返回null;,java,concurrenthashmap,Java,Concurrenthashmap,} 当tabAt(tab,i=(n-1)&hash))为null时,它使用CAS添加/修改节点,但当不为null时,它使用同步(f)。我认为它仍然可以使用最后一个节点的CA或需要放入tabAt(tab,I=(n-1)&hash))键的节点来添加/修改节点。但为什么不呢?我的想法是错误的。如果f存在,那么它将遍历并修改树或列表数据结构。这不可能以原子方式就地完成,因此他们需要在整个过程中进行一次写时拷贝(最终CAS可能会导致在concurreny面前重新进行拷贝),或者用一个同步块锁定整个结构。你

}


tabAt(tab,i=(n-1)&hash))
null
时,它使用CAS添加/修改节点,但当不为null时,它使用
同步(f)
。我认为它仍然可以使用最后一个节点的CA或需要放入
tabAt(tab,I=(n-1)&hash))
键的节点来添加/修改节点。但为什么不呢?我的想法是错误的。

如果
f
存在,那么它将遍历并修改树或列表数据结构。这不可能以原子方式就地完成,因此他们需要在整个过程中进行一次写时拷贝(最终CAS可能会导致在concurreny面前重新进行拷贝),或者用一个同步块锁定整个结构。你能发布到源代码的链接吗?这些东西在JDK版本之间会发生变化。
final V putVal(K key, V value, boolean onlyIfAbsent) {
if (key == null || value == null) throw new NullPointerException();
int hash = spread(key.hashCode());
int binCount = 0;
for (Node<K,V>[] tab = table;;) {
    Node<K,V> f; int n, i, fh;
    if (tab == null || (n = tab.length) == 0)
        tab = initTable();
    else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
        if (casTabAt(tab, i, null,
                     new Node<K,V>(hash, key, value, null)))
            break;                   // no lock when adding to empty bin
    }
    else if ((fh = f.hash) == MOVED)
        tab = helpTransfer(tab, f);
    else {
        V oldVal = null;
        synchronized (f) {
            if (tabAt(tab, i) == f) {
                if (fh >= 0) {
                    binCount = 1;
                    for (Node<K,V> e = f;; ++binCount) {
                        K ek;
                        if (e.hash == hash &&
                            ((ek = e.key) == key ||
                             (ek != null && key.equals(ek)))) {
                            oldVal = e.val;
                            if (!onlyIfAbsent)
                                e.val = value;
                            break;
                        }
                        Node<K,V> pred = e;
                        if ((e = e.next) == null) {
                            pred.next = new Node<K,V>(hash, key,
                                                      value, null);
                            break;
                        }
                    }
                }
                else if (f instanceof TreeBin) {
                    Node<K,V> p;
                    binCount = 2;
                    if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                   value)) != null) {
                        oldVal = p.val;
                        if (!onlyIfAbsent)
                            p.val = value;
                    }
                }
            }
        }
        if (binCount != 0) {
            if (binCount >= TREEIFY_THRESHOLD)
                treeifyBin(tab, i);
            if (oldVal != null)
                return oldVal;
            break;
        }
    }
}
addCount(1L, binCount);
return null;