Подтвердить что ты не робот

Vector vs Collections.synchronizedList(ArrayList)

Вектор синхронизирован, ArrayList не синхронизирован, но мы можем синхронизировать ArrayList с помощью Collections.synchronizedList(aList), так что будет работать лучше и быстрее?

4b9b3361

Ответ 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 и сохранять себя при выполнении всех этих синхронизированных вызовов.

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