当新的ArrayList时为null

时间:2019-01-15 10:41:15

标签: java arraylist nullpointerexception

观看在线产品时出现错误,代码是这样的,但是NullPointedException困扰着我,此错误仅出现一次,并且我无法再次出现。我不明白为什么ArrayList[null, 1]

public void test4() {
    class PlayerTask {
        List<Integer> targetValueList;

        List<Integer> getTargetValueList() {
            if (null == targetValueList) {
                init();
            }
            return targetValueList;
        }

        private void init() {
            targetValueList = new ArrayList<>();
            targetValueList.add(Integer.parseInt("1"));
        }
    }
    PlayerTask task = new PlayerTask();

    //some code1
    new Thread(() -> {
        task.getTargetValueList().get(0); // NullPointException ,real array is [null, 1]
    }).start();

    //some code2
    new Thread(() -> {
        task.getTargetValueList().size();
    }).start();

    // some code ...
    new Thread(() -> {
        task.getTargetValueList().get(0);
    }).start();

    // ....
    ///task.getTargetValueList().get(..)...
}

1 个答案:

答案 0 :(得分:4)

您的代码是多线程的,但是在创建和访问new ArrayList<>()时您无法防范可能的race condition。解决此问题的最快方法是使用synchronize getTargetValueList()方法:

synchronized List<Integer> getTargetValueList() {
    if (null == targetValueList) {
        init();
    }
    return targetValueList;
}

花点时间阅读Safe Publication and Safe Initialization in Java。它为如何改进此方法提供了深刻的见解,以及为什么像双重检查锁定之类的某些模式不是一个好主意。

如果您想了解有关并发的更多信息,那么本书Java Concurrency in Practice是一个很好的起点。