Я использую Collections.synchronizedCollection в Java для защиты набора, который, как мне известно, получает доступ одновременно несколькими потоками. Java API предупреждает:synchronizedCollection и содержит - мне нужно синхронизировать вручную?
«Крайне важно, чтобы пользователь вручную синхронизировать возвращенной коллекции при переборе над ним:
Collection c = Collections.synchronizedCollection(myCollection);
...
synchronized(c) {
Iterator i = c.iterator(); // Must be in the synchronized block
while (i.hasNext())
foo(i.next());
}
»
Если я использую c.contains(obj)
, что поточно-? Внутри, очевидно, это итерация по коллекции и наблюдение, если какой-либо из объектов в ней равен obj. Мой инстинкт состоит в том, чтобы предположить, что это, вероятно, синхронизировано (казалось бы, это серьезный провал, если нет), но, учитывая предыдущие проблемы с синхронизацией, кажется разумным дважды проверить, и поиск Google ответов на это не превратился все что угодно.
Это хороший момент; Я не считал, что добавляю к нему ценность, если ее там нет. В этом случае кажется очевидным, что мне придется вручную синхронизировать. – DivineWolfwood
И в таком случае, почему бы просто не добавить его? Что делает базовая реализация? Например, для HashSet a содержит, а затем добавление делает двойную работу только добавить. В вашем случае, независимо от добавления реализации Set, это будет атомная операция в отношении синхронизации, и ваш код add() должен обрабатывать дубликаты в любом случае (даже если сам он просто проверяет contains()), чтобы правильно выполнить контракт Добавить(). – PSpeed
@PSpeed: Отличное предложение. Это избавляет меня от необходимости выполнять синхронизацию, потому что я все равно добавляю ее. – DivineWolfwood