Вектор синхронизирован, ArrayList не синхронизирован, но мы можем синхронизировать ArrayList с помощью Collections.synchronizedList(aList)
, так что будет работать лучше и быстрее?
Vector vs Collections.synchronizedList(ArrayList)
Ответ 1
Синхронизированные коллекции являются пустой тратой времени и опасны. Тривиальный пример, почему они плохие, состоит в том, чтобы рассмотреть два потока, запускающих цикл в одно и то же время в одной коллекции:
int i = 0;
while (i < list.size())
{
if (testSomeCondition(list.get())) {
list.remove(i);
else
i++;
}
Наш список может быть синхронизирован (например, Vector), и этот код все равно будет прерываться. Зачем? Поскольку индивидуальные вызовы size(), get(), remove(), синхронизируются, но один поток все равно может удалять элементы из списка, а другой - итерации по нему. Другими словами, у нас есть условие гонки, и использование синхронизированных коллекций ничего нам не принесло.
Чтобы исправить гонку, мы должны синхронизировать всю операцию с коллекцией или использовать Java 5 concurrency Locks, чтобы сделать то же самое.
synchronized (list) {
int i = 0;
while (i < list.size())
{
if (testSomeCondition(list.get())) {
list.remove(i);
else
i++;
}
}
Этот блок кода теперь является потокобезопасным, поскольку только один поток может выполнять цикл за раз. И теперь нет причин использовать синхронизированную коллекцию. Мы можем использовать ArrayList вместо Vector и сохранять себя при выполнении всех этих синхронизированных вызовов.
Поэтому не используйте синхронизированные коллекции. Если вы обнаружите, что несколько потоков попали в один и тот же список, вам необходимо защитить операции в списке, а не отдельные вызовы.