Вектор по сравнению с Collections.synchronizedList(ArrayList)

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

36
задан rogerdpack 19 July 2016 в 19:52
поделиться

1 ответ

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

int i = 0;
while (i < list.size())
{
  if (testSomeCondition(list.get())) {
    list.remove(i);
  else
    i++;
}

Наш список может быть синхронизирован (например, вектор), и этот код все равно ужасно сломается. Почему? Поскольку отдельные вызовы size (), get (), remove () синхронизированы, но один поток все еще может удалять элементы из списка, в то время как другой выполняет итерацию по нему. Другими словами, у нас есть состояние гонки, и использование синхронизированных коллекций нам ничего не дало.

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

synchronized (list) {
  int i = 0;
  while (i < list.size())
  {
    if (testSomeCondition(list.get())) {
      list.remove(i);
    else
      i++;
  }
}

Этот блок кода теперь является потокобезопасным, поскольку только один поток может выполнять цикл за раз. И теперь нет смысла использовать синхронизированную коллекцию. Мы можем использовать ArrayList вместо Vector и сэкономить на производительности для всех этих синхронизированных вызовов.

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

5
ответ дан 27 November 2019 в 06:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: