gpt4 book ai didi

java - 奇怪的 HashMap 异常(HashMap$Node 无法转换为 HashMap$TreeNode)

转载 作者:IT老高 更新时间:2023-10-28 21:13:04 37 4
gpt4 key购买 nike

在 stackoverflow 上提出另一个问题后,(Java- Why this program not throwing concurrent Modification exception)我开始尝试使用 HashMap。下面是我写的几行代码:

import java.util.HashMap;
import java.util.Random;

public class Concurrency {
public static void putEntriesToMap(HashMap<String, String> hashMap) {
for (int count = 0; count < 10000; count++) {
hashMap.put(Integer.toString(count), Integer.toString(count));
Random random = new Random();
if (random.nextBoolean()) {
hashMap.remove(count + "");
}
}
}

public static void main(String[] args) throws InterruptedException {
final HashMap<String, String> hashMap = new HashMap<String, String>();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
putEntriesToMap(hashMap);
}
});

Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
putEntriesToMap(hashMap);
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}

曾几何时(大约 20 次运行中的 1 次),执行此代码时,我得到

Exception in thread "Thread-0" Exception in thread "Thread-1" java.lang.ClassCastException: java.util.HashMap$Node cannot be cast to java.util.HashMap$TreeNode
at java.util.HashMap$TreeNode.moveRootToFront(HashMap.java:1819)
at java.util.HashMap$TreeNode.treeify(HashMap.java:1936)
at java.util.HashMap.treeifyBin(HashMap.java:771)
at java.util.HashMap.putVal(HashMap.java:643)
at java.util.HashMap.put(HashMap.java:611)
at Concurrency.putEntriesToMap(Concurrency.java:9)
at Concurrency$1.run(Concurrency.java:27)
at java.lang.Thread.run(Thread.java:745)

然而,这对我来说似乎很奇怪,因为它看起来像是一个内部 HashMap 错误。我知道并发没有正确使用,但它是故意

我试图用谷歌搜索异常,但我几乎找不到任何信息。

你能重现同样的异常吗?

我正在使用 oracle jdk 1.8.0_40

编辑:

首先,感谢您的回答,我现在很清楚了。我只想指出,我知道如何通过使用线程安全预防措施来避免程序中断,但我不知道为什么在特定情况下会抛出这个异常。托马斯在下面的评论中很好地解释了它。在接受的答案中也很好地解释了这一点。再次感谢:)。

最佳答案

我还发现您的代码存在相同的异常。我在 putEntriesToMap() 方法上添加了 synchronized 修饰符,错误似乎停止发生。问题是两个线程同时修改同一个映射。有一个对象必须被转换才能放入条目。但是,第二个线程正在处理一个变异的对象,它会抛出一个 ClassCastException。因此,请确保没有两个线程同时访问同一个映射。如果另一个线程正在做同样的事情,synchronized 修饰符会阻止所有其他线程对类/实例执行任何操作。同步的静态方法同步类本身,而同步的非静态方法只同步类的实例。

关于java - 奇怪的 HashMap 异常(HashMap$Node 无法转换为 HashMap$TreeNode),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29967401/

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