code-life balance
code-life balance

Reputation: 319

NullPointerException occurred when put something into map concurrently

I use a map to store data by running several sqls. Recently I wanna improve the efficiency of searching, so I create some threads, each thread corresponds to each sql, then put query results into the map at the same time. When running the code, I get NullPointerExceptions but do not know why. Here is my code:

public Map<String, Object> getIndexStatistics(final Integer themeId, final String time, final Integer projectId) {
    final Map<String, Object> res = new ConcurrentHashMap<>();
    final AtomicInteger ai = new AtomicInteger(0);
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part1", getSumVolume(themeId, time, true, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part2", getVolumeTendency(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part3", getPlatformDistribution(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part4", getFeelingProportion(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part5", getLocationDistribution(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part6", getPositiveCloudList(themeId, time));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part7", getNegativeCloudList(themeId, time));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part8", getLatestNegativeSentiments(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("part9", getHotRank(themeId, time, null, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("statistic_counts", getCountStatistics(time, themeId, projectId));
            ai.getAndIncrement();
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            res.put("region_counts", getRegionDistribution(themeId, time, projectId));
            ai.getAndIncrement();
        }
    }).start();
    while (true) {
        if (ai.get() == 11) {
            break;
        }
    }
    return res;
}

stacktrace:

java.lang.NullPointerException
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    at java.util.concurrent.ConcurrentHashMap.put(ConcurrentHashMap.java:1006)
    at com.bolaa.main.service.impl.ProjectNameDataServiceImpl$7.run(ProjectNameDataServiceImpl.java:309)
    at java.lang.Thread.run(Thread.java:748)

By the way, all of the operations are addings and puttings. Do I need to use AtomicInteger and ConcurrentHashMap?

Upvotes: 0

Views: 3940

Answers (1)

user9799449
user9799449

Reputation:

You can use another type of Thread Pools [1] to improve the efficiency and testing result of functions.

The problem is one function doesn't return a value [2]. Like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value.[2]

You can change the argument of function to value 123 in all threads, and to find the error function. or testing

final int errno= -1
if(getFeelingProportion(themeId, time, projectId)==null)
        res.put("part4", errno);
else
        res.put("part4", getFeelingProportion(themeId, time, projectId));
ai.getAndIncrement();

[1] https://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html [2] https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html

Upvotes: 3

Related Questions