Вектор синхронизирован, ArrayList не синхронизирован, но мы можем синхронизировать ArrayList на Collections.synchronizedList(aList)
, так что будет работать лучше и быстрее?Vector vs Collections.synchronizedList (ArrayList)
ответ
Синхронизированные коллекции являются пустой тратой времени и опасны. Тривиальный пример, почему они плохо рассмотреть две темы запуска цикла в то же время на одной и той же коллекции:
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 и сэкономить себе штраф за выполнение всех этих синхронизированных вызовов.
Поэтому не используйте синхронизированные коллекции. Если вы обнаружите, что несколько потоков попадают в один и тот же список, вам необходимо защитить операции в списке, а не отдельные вызовы.
«Синхронизированные коллекции - пустая трата времени». - слишком общий. Цели, связанные с синхронизацией. Вы просто приводите пример того, как использовать их неправильно. Соломенный аргумент. – thejoshwolfe
Они являются пустой тратой времени буквально. Синхронизированное ключевое слово налагает штраф за вызов, даже если коллекция используется исключительно одним потоком. И большинство коллекций будут использоваться исключительно одним потоком. И даже если они разделены, синхронизация индивидуального вызова по-прежнему позволяет использовать условия гонки, поэтому они не подходят для цели. Разработчик просто тратит свое время на поиск ошибок в своих якобы потокобезопасных коллекциях. Проще говоря, эти коллекции токсичны и никогда не должны использоваться, кроме случаев, когда их не избежать (например, устаревшие случаи, J2ME и т. Д.). – locka
Синхронизация была медленной в java 1.3 и ранее. В современной java это лучше. http://www.ibm.com/developerworks/java/library/j-jtp04223/index.html Кроме того, опять же с соломенными соображениями. Никто не использует синхронизацию с ситуацией, которая, как известно, является однопоточной. Ваш первый пример - просто плохое программирование, и никакая коллекция никогда не сможет это компенсировать. Вы просто должны думать о том, что является или не является атомом, независимо от того, какую коллекцию вы используете. Взгляните на код remove() в ArrayList, и вы поймете, почему этот метод необходимо синхронизировать для поддержания целостности списка. – Gus
Если это C#, пожалуйста, пометьте свой вопрос «C#» или «.NET». – FrustratedWithFormsDesigner
Почему бы вам не написать тест и не узнать? – skaffman
Можете ли вы объяснить шаблон использования? 1) Многие записи/многие читают 2) Мало пишет, многие читают, 3) Многие пишут, мало читает 4) Немного/немного не нуждается в оптимизации – TJR