(Ответ был написан для более ранней версии вопроса ).
Нет, синхронизировать его не нужно, потому что вы никогда не изменяете список структурно.
Вы добавляете в список, только если он не пустой.Поэтому вы никогда не добавляете в него первый элемент.
Это почти наверняка логический недостаток, но он отвечает на вопрос в том виде, в котором он написан.
Предполагается, что вы исправили логику и можете добавлять элементысписок, и вы хотите вызвать его из нескольких потоков, да, он должен быть синхронизирован.
Но причина этого кроется в , а не , что ArrayList
четко задокументировано как требующая синхронизации, когдадоступ из нескольких потоков (хотя указывает, что синхронизация должна быть задействована каким-либо образом):
Обратите внимание, что эта реализация не синхронизирована .Если несколько потоков обращаются к экземпляру ArrayList одновременно, и хотя бы один из потоков структурно изменяет список, он должен быть синхронизирован извне.(Структурная модификация - это любая операция, которая добавляет или удаляет один или несколько элементов или явно изменяет размер базового массива; просто установка значения элемента не является структурной модификацией.)
Это то, что вывыполняют сложные действия над списком: если список не пуст, удалите его последний элемент;затем добавьте новый элемент .
Этот первый бит (, если список не пуст, удалить его последний элемент ) может быть испорчен несколькими потоками.Например, два потока могут одновременно найти список размером 1;затем один поток удаляет последний элемент перед другим;затем другой поток пытается удалить удаленный элемент.Kaboom.
Или добавление может быть испорчено, если оба потока обнаружат, что список пуст, и поэтому не пытайтесь удалить что-либо;затем добавьте, и вы получите два элемента в списке.
Даже если вы используете Collections.synchronizedList
, как рекомендовано в документации ArrayList
, это не решит вашу проблему.Важно понимать, что приведенная выше цитата - это то, что вы должны сделать, чтобы сохранить инварианты из ArrayList
;он ничего не делает для принудительного применения инвариантов вашего кода.
Вы должны быть в состоянии выполнить эту логику атомарно .Все это делается как «одно действие» одним потоком с монопольным доступом к списку.Это достигается путем синхронизации.