Как ArrayList <Integer>хранит нулевое значение в приведенной ниже программе? - PullRequest
0 голосов
/ 08 октября 2018
public class SampleExecutorService {
    private int count = 0;
    List<Integer> numbers = new ArrayList<>();
    private void increment() {
        count++;
        numbers.add(count);
    }

    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        SampleExecutorService obj = new SampleExecutorService();
        Runnable task = obj::increment;

        for (int i = 0; i < 20; i++) {
            executorService.submit(task);

        }
        executorService.shutdown();

        try {
            executorService.awaitTermination(2, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        obj.numbers.stream().forEach(System.out::println);
        System.out.println("count : " + obj.numbers.size());
    }   
}

Я просто увеличиваю счетчик и добавляю это значение в список массивов.Иногда он хранит ожидаемые значения, но иногда нет (ArrayList<Integer> содержит значения 'null').Пожалуйста, помогите мне в этом вопросе.

1 Ответ

0 голосов
/ 08 октября 2018

Из Javadoc ArrayList:

Обратите внимание, что эта реализация не синхронизирована .Если несколько потоков обращаются к экземпляру ArrayList одновременно, и хотя бы один из потоков структурно изменяет список, он должен быть внешне синхронизирован.

Вы добавляете элементы из нескольких потоков, но не синхронизируете их внешне,Таким образом, вы можете увидеть неопределенное поведение в списке - например, null элементов, когда вы фактически никогда не добавляете ноль.

Вы можете исправить это тривиально, используя подсказку в Javadoc:

List<Integer> numbers = Collections.synchronizedList(new ArrayList<>());

(Обратите внимание, что вы можете увидеть другое «неожиданное» поведение, например, добавление одного и того же числа дважды, потому что count не увеличивается атомарно или элементы не в правильном порядке в списке)

...