由于并发访问,TreeMap 中是否存在此空指针异常? [英] Is this null pointer exception in TreeMap due to concurrent access?

查看:96
本文介绍了由于并发访问,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)

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

推荐答案

NullPointerException 是否是并发修改的直接结果,它声明 TreeMap 的 Javadoc 中:

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.

添加外部同步:)

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆