Вектор против коллекций.synchronizedList (ArrayList) - PullRequest
35 голосов
/ 21 мая 2010

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

1 Ответ

4 голосов
/ 23 августа 2010

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

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

Наш список может быть синхронизирован (например, Vector), и этот код все равно будет ужасно прерываться,Зачем?Поскольку отдельные вызовы 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 и сэкономить на производительности всех синхронизированных вызовов.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...