Вы синхронизирующие дважды, что не имеет смысла, и, возможно, замедляет код: изменения в то время как итерация по списку нуждающемуся synchronnization в течение всей операции , которое вы делаете с synchronized (in_queue_list)
Использование Collections.synchronizedList()
является излишним в этом случае (он создает обертку, которая синхронизирует отдельные операции).
Однако, поскольку вы полностью опустошаете список, повторное удаление первого элемента является наихудшим возможным способом его выполнения. Для каждого элемента необходимо скопировать все следующие элементы, что делает это O (n^2) операция - ужасно медленная для больших списков.
Вместо этого просто позвоните clear()
- не требуется итерации.
Edit: Если вам нужна синхронизация одного метода из Collections.synchronizedList()
позже, то это правильный путь:
List<Record> in_queue_list = Collections.synchronizedList(in_queue);
in_queue_list.clear(); // synchronized implicitly,
Но во многих случаях, синхронизация одного метода недостаточно (например, для всей итерации или когда вы получаете значение, делайте вычисления на основе этого и замените его результатом). В этом случае вы должны использовать ручную синхронизацию в любом случае, так что Collections.synchronizedList()
- это просто бесполезные дополнительные накладные расходы.
Вы не можете обновить список для синхронизации, потому что вам передается ссылка, поэтому вы действительно не владеете ею. Все, что дало вам ссылку, все равно может изменить исходный список, который он передал вам одновременно. Независимо от того, какую синхронизацию вы добавляете, если явно не известно, что этот список будет защищен встроенной блокировкой. –
Я буду помещать синхронизированный блок вокруг любой операции в очереди. Благодаря! – bob