gpt4 book ai didi

java - 证明 hashMap 是故障安全的代码

转载 作者:行者123 更新时间:2023-11-29 06:00:43 26 4
gpt4 key购买 nike

问题已编辑:
如代码中所述,HashSet 和 HashMap 是快速失败的(但这不是保证):

void goHashSet() {
Set set = new HashSet();
for (int i = 1; i <= 10; i++) {
set.add(i);
}
Iterator i = set.iterator();
while (i.hasNext()) {
// set.add(16);//Exception in thread "main"
// java.util.ConcurrentModificationException
System.out.println("HashSet >>> itertor >>>" + i.next());
}
}

现在,我想要故障安全的示例和集合
据我所知:ConcurrentHashMap、CopyOnWriteArrayList 是故障安全的..但是如何对其进行编码以表明它们是故障安全的

编辑和理解我想要的以及我是如何实现它的:

如果我们使用HashMap

void goHashMap() {
Map mp = new HashMap();
for (int i = 19; i <= 24; i++) {
mp.put(i, "x");
}
Set setKeys = mp.keySet();
Iterator i = setKeys.iterator();
while (i.hasNext()) {
// mp.put(499, "x");// Exception in thread "main"
// java.util.ConcurrentModificationException
System.out.println("HashMap >>> itertor >>>" + i.next());
}
}

我们得到 ConcurrentMException

但是同样的代码用ConcurrentHashMap完成,没有报错(非多线程环境)

void goConcurrentHashMap() {
Map mp = new ConcurrentHashMap();
for (int i = 19; i <= 24; i++) {
mp.put(i, "x");
}
Set setKeys = mp.keySet();
Iterator i = setKeys.iterator();
while (i.hasNext()) {
mp.put(499, "x");
System.out.println("HashConcurrentMap >>> itertor >>>" + i.next());
}
}

更多:在多线程环境中,ConcurrentHashmap 可能会快速失败并抛出异常 CME

最佳答案

HashMap 不保证是故障安全的。您仍然可以在不同的线程中修改 HashMap 并且不会注意到另一个线程。 HashMap 的 OpenJDK 版本使用非 volatile modcount 字段来识别并发修改。由于不保证非 volatile 字段在线程之间保持一致,一个线程可以更改它而另一个线程无法注意到它的更改。

这是一种相对罕见的竞争条件,因此很可能会检测到 CME,但即使您对其进行测试并且它连续 10000 次按预期运行,这也无法提供您可能的证据寻找。

事实上,可以编写将通过前 10000 次并在之后一直失败的代码。这是因为 HotSpot 编译将在这一点之后编译为 native 代码。这意味着在优化前运行正常的代码在优化后可能会表现不同。 esp 用于非 volatile 字段。

关于java - 证明 hashMap 是故障安全的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10206188/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com