Java 如何在ConcurrentHashMap(JDK1.8或更高版本)的addCount函数中实现条件(sc==rs+;1 | | sc==rs+;MAX_RESIZERS)
我在ConcurrentHashMap中阅读了Java 如何在ConcurrentHashMap(JDK1.8或更高版本)的addCount函数中实现条件(sc==rs+;1 | | sc==rs+;MAX_RESIZERS),java,java-8,java.util.concurrent,Java,Java 8,Java.util.concurrent,我在ConcurrentHashMap中阅读了addCount函数的源代码, 但是我不明白什么时候可以达到条件(sc==rs+1 | | sc==rs+MAX_RESIZERS) 为什么不使用sc==(rs我已将此问题作为错误报告提交给Oracle。它已通过评估,并在jdk错误数据库中显示,错误id为:jdk-8214427 以下是错误报告的链接:。请注意,由于我的错误,错误报告中给出的修复方法是错误的 总结: 条件 sc == rs + 1 ||sc == rs + MAX_RESI
addCount
函数的源代码,
但是我不明白什么时候可以达到条件(sc==rs+1 | | sc==rs+MAX_RESIZERS)
为什么不使用
sc==(rs我已将此问题作为错误报告提交给Oracle。它已通过评估,并在jdk错误数据库中显示,错误id为:jdk-8214427
以下是错误报告的链接:。请注意,由于我的错误,错误报告中给出的修复方法是错误的
总结:
条件
sc == rs + 1
||sc == rs + MAX_RESIZERS
( sc == rs + 1 || sc == rs + MAX_RESIZERS)
应改为
sc == ( rs<<<RESIZE_STAMP_SHIFT ) +1 || sc == ( rs<<<RESIZE_STAMP_SHIFT ) + MAX_RESIZERS
sc==(这是一个问题?还是一个错误报告?坦率地说,这并不清楚。请阅读这里的问题。这是一个问题,我希望有人能帮助我确认我是否错了。你能发布一篇文章来演示这个问题吗?@Carlos Heuberger我想这个问题只能通过以下场景来验证:有超过最大的resizer
threads在同一个ConcurrentHashMap上进行大小调整,很难模拟这种情况。因为通常,在更多线程加入同一轮大小调整过程之前,大小调整已经完成@Carlos Heuberger感谢您的启发,我复制了源代码,并做了一个小实验。我将在我的问题中添加它
if (nextTab == null) { // initiating
try {
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];
nextTab = nt;
} catch (Throwable ex) { // try to cope with OOME
sizeCtl = Integer.MAX_VALUE;
return;
}
nextTable = nextTab;
transferIndex = n;
}
// The following added code here is to suspend Threads !!!!
try {
String s = new String();
synchronized (s)
{
s.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
( sc == rs + 1 || sc == rs + MAX_RESIZERS)
sc == ( rs<<<RESIZE_STAMP_SHIFT ) +1 || sc == ( rs<<<RESIZE_STAMP_SHIFT ) + MAX_RESIZERS
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) << RESIZE_STAMP_SHIFT;
if (sc < 0) {
if (sc == rs + MAX_RESIZERS || sc == rs + 1 ||
(nt = nextTable) == null || transferIndex <= 0)
break;
if (U.compareAndSetInt(this, SIZECTL, sc, sc + 1))
transfer(tab, nt);
}
else if (U.compareAndSetInt(this, SIZECTL, sc, rs + 2))
transfer(tab, null);
s = sumCount();
}
}