简体   繁体   中英

Is this null pointer exception in TreeMap due to concurrent access?

I know that TreeMap is not thread safe. I am trying to do a comparison of TreeMap with ConcurrentSkipListMap . Code I use is shown below and I want to make sure if the error I am getting is due TreeMap not being threadsafe and not because of some other.

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$1.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");
}
}

Whether or not the NullPointerException is a direct result of the concurrent modification, it states 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.

As you are modifying the map in multiple threads without synchronization, you are not using the class as it is intended to be used.

Add external synchronization :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM