Лучший подход зависит от того, что именно ваш код пытается сделать, и от уровня атомарности, который вам требуется. Иногда Collections.synchronizedWhatever
в порядке; иногда вам нужно выполнить собственную синхронизацию.
С точки зрения производительности вам просто нужно убедиться, что вы минимизируете количество вводимых блоков synchronized
. Там будет небольшая разница между
(example A)
List l = Collections.synchronizedList(originalList);
l.add(something);
и
(example B)
synchronized (originalList) {
originalList.add(something);
}
потому что они оба входят в один синхронизированный блок. Однако:
(example C)
List l = Collections.synchronizedList(originalList);
l.add(something);
int index = l.indexOf(something);
введет два синхронизированных блока, тогда как
(example D)
synchronized (originalList) {
originalList.add(something);
int index = originalList.indexOf(something);
}
войдет только в один синхронизированный блок. Конечно, он тратит больше времени в этом блоке, так что это может увеличить конкуренцию, но add и indexOf теперь ведут себя как одна атомарная операция. Это может или не может быть тем, что вы хотите: это полностью зависит от приложения.
РЕДАКТИРОВАТЬ: Чтобы ответить на вопрос Дипака:
'synchronizedList' в примере C означает, что каждый вызов метода в 'l' будет заключен в синхронизированный блок. Вы можете думать о C как об этом:
synchronized (originalList) {
originalList.add(something);
}
synchronized (originalList) {
int index = originalList.indexOf(something);
}
Здесь есть некоторая дополнительная стоимость, но, если она не находится в критической части вашего кода, это, вероятно, не будет проблемой. Я бы посоветовал вам больше задуматься о том, чтобы убедиться, что ваш код ведет себя правильно, прежде чем подумать об его оптимизации. Трудно сделать правильный потокобезопасный код, поэтому будьте очень осторожны с тем, как вы пишете вещи. Например, в C существует возможное состояние гонки между «l.add (что-то)» и «l.indexOf (что-то)». У D нет одинакового состояния гонки, потому что обе операции находятся внутри одного синхронизированного блока.
Книга Брайана Гетца (Java Concurrency in Practice) является отличным ресурсом для обучения написанию поточно-ориентированного кода. Я очень рекомендую это. Я уверен, что это на Амазоне.