TreeMap中的这个空指针异常是不是并发访问导致的?
Is this null pointer exception in TreeMap due to concurrent access?
我知道 TreeMap is not thread safe. I am trying to do a comparison of TreeMap with ConcurrentSkipListMap。我使用的代码如下所示,我想确定我得到的错误是否是由于 TreeMap 不是线程安全的,而不是因为其他原因。
Exception in thread "pool-1-thread-52" java.lang.NullPointerException
at java.util.TreeMap.rotateLeft(TreeMap.java:2060)
at java.util.TreeMap.fixAfterInsertion(TreeMap.java:2127)
at java.util.TreeMap.put(TreeMap.java:574)
at ThreadTestTreeMap.run(ThreadTestTreeMap.java:39)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at 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");
}
}
无论 NullPointerException
是否是并发修改的直接结果,它表示 in the Javadoc for TreeMap
:
Note that this implementation is not synchronized. If multiple threads access a map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.
由于您在没有同步的情况下在多个线程中修改地图,因此您没有按预期使用 class。
添加外部同步:)
我知道 TreeMap is not thread safe. I am trying to do a comparison of TreeMap with ConcurrentSkipListMap。我使用的代码如下所示,我想确定我得到的错误是否是由于 TreeMap 不是线程安全的,而不是因为其他原因。
Exception in thread "pool-1-thread-52" java.lang.NullPointerException at java.util.TreeMap.rotateLeft(TreeMap.java:2060) at java.util.TreeMap.fixAfterInsertion(TreeMap.java:2127) at java.util.TreeMap.put(TreeMap.java:574) at ThreadTestTreeMap.run(ThreadTestTreeMap.java:39) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at 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");
}
}
无论 NullPointerException
是否是并发修改的直接结果,它表示 in the Javadoc for TreeMap
:
Note that this implementation is not synchronized. If multiple threads access a map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally.
由于您在没有同步的情况下在多个线程中修改地图,因此您没有按预期使用 class。
添加外部同步:)