我一直在查看以下代码(来自here https://hg.openjdk.java.net/jdk/jdk13/file/0368f3a073a9/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java)'
/**
* Initializes table, using the size recorded in sizeCtl.
*/
private final Node<K,V>[] initTable() {
Node<K,V>[] tab; int sc;
while ((tab = table) == null || tab.length == 0) {
if ((sc = sizeCtl) < 0)
Thread.yield(); // lost initialization race; just spin
else if (U.compareAndSetInt(this, SIZECTL, sc, -1)) {
try {
if ((tab = table) == null || tab.length == 0) {
int n = (sc > 0) ? sc : DEFAULT_CAPACITY;
@SuppressWarnings("unchecked")
Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];
table = tab = nt;
sc = n - (n >>> 2);
}
} finally {
sizeCtl = sc;
}
break;
}
}
return tab;
}
有人可以解释为什么需要 try 块吗?
未经检查的异常和错误作为一个概念而存在。如果你打电话.put()
在 ConcurrentHashMap 上,并且内存非常紧张,该映射可能会尝试创建一个数组,并且该调用可能会因 OutOfMemoryError 而失败。代码仍将继续(也许在捕获此内容的 catch 块处),并且对该映射的引用仍然存在。如果发生这种情况后,地图崩溃并完全失效,因为 sizeCtl 的值已损坏,那就有点糟糕了。
重点是finally 块,它恢复了sizeCtl
价值。这用于多种用途,值得注意的是包括管理哪个线程可以访问。如果没有,任何其他看跌期权都将永远旋转。
其相关性(例如,这里发生可抛出的频率,与删除“尝试”和“最后”并以结尾sizeCtl = sc;
没有 try/finally 的额外开销)很低,但如果相关的话,它是相当相关的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)