ArrayLists не синхронизированы и, следовательно, быстрее, чем Vector, но менее безопасны в многопоточной среде.
Я хотел бы знать, почему несинхронизация может улучшить скорость и почему она будет менее безопасной?
Когда несколько потоков читают / записывают в общую память, программа может вычислить неверные результаты из-за отсутствия взаимного исключения и надлежащей видимости.Следовательно, отсутствие синхронизации считается «небезопасным». Это сообщение в блоге Джереми Мэнсона может послужить хорошим введением в тему.
Когда JVM выполняет синхронизированный метод, он гарантирует, что текущий поток имеет монопольную блокировку объекта накакой метод вызывается.Точно так же, когда метод заканчивает выполнение, JVM освобождает блокировку, удерживаемую исполняющим потоком.Синхронизированные методы обеспечивают взаимное исключение и гарантии видимости - и это важно для «безопасности» (т. Е. Обеспечения правильности) исполняемого кода.Но, если только один поток когда-либо обращается к методам объекта, нет проблем с безопасностью.Несмотря на то, что производительность JVM улучшилась за прошедшие годы, бесконтрольная синхронизация (т.е. блокировка / разблокировка объектов, к которым обращается только один поток), все же занимает ненулевое количество времени.Для несинхронизированных методов JVM не платит этот дополнительный штраф - следовательно, они быстрее, чем их синхронизированные аналоги.
Vector
s навязывают вам свой выбор.Все методы synchronized
, и их сложно использовать неправильно.Но когда Vector
s используются в однопоточном контексте, вы платите цену за дополнительную синхронизацию без необходимости.ArrayList
ы оставляете за вами выбор.При использовании в многопоточном контексте, вы (программист) должны правильно синхронизировать код;но при использовании в однопоточном контексте вы гарантированно не будете платить лишние затраты на синхронизацию.
Кроме того, при первоначальном заполнении коллекции и последующем чтении ArrayList
работают лучше даже в многопоточном контексте.Например, рассмотрим этот метод:
public synchronized List<String> getList() {
List<String> list = new Vector<String>();
list.add("Foo");
list.add("Bar");
return Collections.unmodifiableList(list);
}
Список создается, заполняется, и его неизменное представление безопасно публикуется.Глядя на приведенный выше код, становится ясно, что все последующие использования этого списка считываются и не требуют какой-либо синхронизации, даже если используются несколькими потоками - объект является эффективно неизменным .Использование Vector
здесь приводит к накладным расходам синхронизации даже для операций чтения, где это не требуется;вместо этого лучше использовать ArrayList
.