Нуль, когда новый ArrayList - PullRequest
0 голосов
/ 15 января 2019

У меня была ошибка при просмотре онлайн-продукта, код такой, но 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 голосов
/ 15 января 2019

Ваш код является многопоточным, но вы не защищаетесь от возможных условий гонки при создании и доступе к new ArrayList<>(). Самый быстрый способ решить эту проблему - метод synchronize getTargetValueList():

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

Найдите минутку, чтобы прочитать Безопасная публикация и безопасная инициализация в Java . Это дает глубокое понимание того, как этот подход может быть улучшен и почему некоторые шаблоны, такие как двойная проверка блокировки, являются плохой идеей.

Если вы хотите узнать больше о параллелизме, книга Параллелизм Java на практике является хорошей отправной точкой.

...