2015-03-30 2 views
0

У меня вопрос о простой ArrayList, а не synchronizedList или CopyOnWriteArrayList. Их можно использовать с несколькими потоками, которые добавляют и получают элементы безопасным образом, используя блок или метод синхронизации? И если да: в какой точке разница между простым ArrayList с синхронизированным блоком и synchronizedList?Можно использовать простой ArrayList в многопоточной программе?

ответ

0

Да, можно использовать ArrayList несколькими потоками с использованием синхронизированных блоков или методов. Фактически, вы проверяете исходный код Collections.synchronizedList(), он делает то же самое. Если вы используете один и тот же объект для синхронизированных методов или блоков для каждого типа доступа (get, add, iterate и т. Д.), Это нормально.

0

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

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

if(!list.contains(x)) { 
    list.add(x); 
} 

, как там может быть одновременным обновление в промежутке между этими двумя вызовами методы (это называется check-then-act anti-pattern).

Таким образом, разница между использованием synchronized блоков с ArrayList и используя результат Collections.synchronizedList(new ArrayList<>()) является то, что synchronizedList будет применяться синхронизации на каждом вызове метода, который будет недостаточным, как только операция состоит из нескольких вызовов, в то время как ручной synchronized блоков предоставить вам полный контроль над тем, когда синхронизировать и какой диапазон кода будет покрыт и в любом случае необходим, даже если вы используете Collections.synchronizedList ...