Ich weiß, dass TreeMap nicht Thread sicher ist. Ich versuche einen Vergleich von TreeMap mit ConcurrentSkipListMap zu machen. Code, den ich benutze, wird unten gezeigt und ich möchte sicherstellen, dass der Fehler, den ich erhalte, darauf zurückzuführen ist, dass TreeMap nicht threadsicher ist und nicht wegen anderer.Ist diese Nullzeiger-Ausnahme in TreeMap aufgrund des gleichzeitigen Zugriffs?
Exception in thread "pool-1-thread-52" java.lang.NullPointerException bei java.util.TreeMap.rotateLeft (TreeMap.java:2060) bei java.util.TreeMap.fixAfterInsertion (TreeMap .java: 2127) bei java.util.TreeMap.put (TreeMap.java:574) bei ThreadTestTreeMap $ 1.run (ThreadTestTreeMap.java:39) bei java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java: 1145) bei java.util.concurrent.ThreadPoolExecutor $ Worker.run (ThreadPoolExecutor.java:615) bei java.lang.Thread.run (Thread.java:745)
import com.google.common.collect.Ordering;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ThreadTestTreeMap {
public static Map<String, Object> map;
public static int THREADS = 100;
public static long averageTime = 0;
public static void main(String args[]) throws InterruptedException {
for (int i = 0; i < 1; i++) {
map = new TreeMap<>(Ordering.natural());
// map = new ConcurrentSkipListMap<>(Ordering.natural());
long time = System.nanoTime();
ExecutorService service = Executors.newFixedThreadPool(THREADS);
for (int j = 0; j < THREADS; j++) {
final int finalJ = j;
service.execute(new Runnable() {
public void run() {
try {
Thread.sleep(THREADS - finalJ);
} catch (InterruptedException e) {
e.printStackTrace();
}
long threadId = Thread.currentThread().getId();
map.put("tag"+threadId, "hello");
}});
}
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
long timeUsed = (System.nanoTime() - time)/1000000L;
averageTime += timeUsed;
System.out.println("All threads are completed in "
+ timeUsed + " ms");
}
System.out.println("The average time is " + averageTime/10 + " ms");
}
}
synchronisieren Zugriff mit synchronisiertem (Karte) {map.put ("tag" + ThreadID, "Hallo"); } und führen Sie den zu überprüfenden Code erneut aus. Wie auch immer, TreeMap ist nicht threadsicher, daher ist GARANTIERT, dass Sie einen Fehler erhalten (NullPointerExcaption oder jede andere Ausnahme oder logischer Fehler, es hängt von der Implementierung ab, siehe Quellen) während gleichzeitiger Änderung. Tatsächlich erhalten Sie undefiniertes Verhalten mit einer Reihe von möglichen Fehlern. – AnatolyG
@AnatolyG Nein, es ist nicht garantiert, dass Sie * eine Ausnahme oder einen logischen Fehler erhalten *; es ist einfach nicht garantiert, dass Sie nicht werden. –
@Andy :) Buchstäblich ja, du hast Recht. Aber das macht mir nichts aus, wenn ich meinen Code schreibe. Ich erwarte das schlimmste MÖGLICHE Szenario. Und du siehst, wie leicht es passiert ist. – AnatolyG