本文介绍了由于并发访问,TreeMap 中是否存在此空指针异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道 TreeMap 不是线程安全.我正在尝试将 TreeMap 与 ConcurrentSkipListMap 进行比较.我使用的代码如下所示,我想确定我得到的错误是否是由于 TreeMap 不是线程安全的,而不是因为其他原因.

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.

线程pool-1-thread-52"中的异常 java.lang.NullPointerException在 java.util.TreeMap.rotateLeft(TreeMap.java:2060)在 java.util.TreeMap.fixAfterInsertion(TreeMap.java:2127)在 java.util.TreeMap.put(TreeMap.java:574)在 ThreadTestTreeMap$1.run(ThreadTestTreeMap.java:39)在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)在 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 是否是并发修改的直接结果,它声明 TreeMap 的 Javadoc 中:

Whether or not the NullPointerException is a direct result of the concurrent modification, it states in the Javadoc for TreeMap:

请注意,此实现不是同步的.如果多个线程同时访问一个映射,并且至少有一个线程在结构上修改了映射,则它必须在外部进行同步.

当您在没有同步的情况下在多个线程中修改映射时,您没有按照预期使用该类.

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

添加外部同步:)

这篇关于由于并发访问,TreeMap 中是否存在此空指针异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 11:37