Синхронизированные коллекции являются пустой тратой времени и опасны.Тривиальный пример, почему они плохи, - это рассмотреть два потока, выполняющих цикл одновременно в одной и той же коллекции:
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 и сэкономить на производительности всех синхронизированных вызовов.
Так что не используйте синхронизированные коллекции.Если вы обнаружите, что несколько потоков попадают в один и тот же список, вам нужно защитить операции в списке, а не отдельные вызовы.