问题已编辑:
如代码中所述,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 字段。
Tôi là một lập trình viên xuất sắc, rất giỏi!