Nach einer anderen Frage auf Stackoverflow, fragte (Java- Why this program not throwing concurrent Modification exception) Ich begann mit der HashMap zu experimentieren. Hier sind ein paar Zeilen Code, die ich schrieb:
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();
}
}
Es war einmal (ca. 1 in 20 Läufen), wenn Sie diesen Code ausführen, bekomme ich
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)
Das aber scheint seltsam zu mir, weil es aussieht wie es ist ein interner HashMap-Fehler. Ich weiß, dass die Nebenläufigkeit wird nicht korrekt verwendet, aber es ist absichtlich getan.
Ich habe versucht, die Ausnahme zu googeln, aber ich habe fast keine Informationen gefunden.
Können Sie die gleiche Ausnahme reproduzieren?
Ich verwende Orakel jdk 1.8.0_40
EDIT:
Erstens Dank für Antworten, es ist für mich jetzt klar. Ich möchte nur darauf hinweisen, dass ich wusste, wie man das Programm durch thread-safe Vorsichtsmaßnahmen zu brechen, aber ich wusste nicht, warum speziell diese Ausnahme in der gegebenen Situation geworfen wird. Thomas hat es in den Kommentaren unten sehr gut erklärt. Es ist auch gut in der angenommenen Antwort erklärt. Danke noch einmal :).
Es ist einfach Folge von "Nebenläufigkeit wird nicht korrekt verwendet" - "HashMap" benötigt externe Synchronisierung thread-safe. –
Das ist möglich, wenn Sie nicht zwischen verschiedenen Threads synchronisieren, was ist die Frage hier? –
Verwenden Sie stattdessen Sammlungen von gleichzeitigen Paketen: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ConcurrentMap.html – Beri