Сделать ваши коллекции потокобезопасными? - PullRequest
9 голосов
/ 02 октября 2008

При разработке класса коллекции, есть ли какая-то причина, чтобы не реализовывать частную блокировку, чтобы сделать ее безопасной для потоков? Или я должен передать эту ответственность потребителю коллекции?

Ответы [ 17 ]

1 голос
/ 02 октября 2008

Обратите внимание, что если вы пытаетесь сделать любой класс потокобезопасным, вам нужно определиться с общими сценариями использования.

Например, в случае коллекции, просто сделать все свойства и методы индивидуально поточно-ориентированными, что может быть недостаточно для потребителя, так как чтение сначала счетчика, а затем цикл или что-то подобное не принесет больших результатов. хорошо, если счет изменился после прочтения.

1 голос
/ 02 октября 2008

Основная причина не делать потокобезопасным - производительность. Потокобезопасный код может быть в 100 раз медленнее небезопасного кода, поэтому, если ваш клиент не хочет использовать эту функцию, это довольно большая трата.

0 голосов
/ 03 декабря 2008

Вот хорошее начало.

потокобезопасной-словарь

Но вы заметите, что теряете одну из замечательных особенностей коллекций - перечисление. Вы не можете поточно-ориентировать перечислитель, это просто нереально, если вы не реализуете свой собственный перечислитель, который удерживает блокировку экземпляра обратно в самой коллекции. Я подозреваю, что это приведет к серьезным узким местам и потенциальным тупикам.

0 голосов
/ 02 октября 2008

Я согласен, что предоставление права потребителю - правильный подход. If предоставляет потребителю гораздо большую гибкость в отношении того, включен ли экземпляр Collection или другой объект. Например, если у вас есть два списка, которые необходимо обновить, может иметь смысл поместить их в один синхронизированный блок с использованием одной блокировки.

0 голосов
/ 02 октября 2008

Это сделает невозможным одновременный доступ к коллекции из нескольких потоков, даже если вы знаете, что элемент, к которому вы прикасаетесь, никем не используется.

Примером может служить коллекция с целочисленным индексатором доступа. Каждый поток может знать из своего идентификатора, к каким значениям индекса он может получить доступ, не беспокоясь о грязных операциях чтения / записи.

Еще один случай, когда вы получите ненужное снижение производительности, - это когда данные считываются только из коллекции, а не записываются в нее.

0 голосов
/ 08 марта 2011

Начиная с JDK 5, если вам нужна потокобезопасная коллекция, я сначала посмотрю, будет ли работать одна из уже реализованных коллекций в java.util.concurrent Как отмечают авторы Java Concurrency In Practice (включая парня, который написал большинство классов), правильно их реализовать очень сложно, особенно если важна производительность.

Цитирование http://download.oracle.com/javase/6/docs/api/java/util/concurrent/package-summary.html

Параллельные коллекции

Помимо очередей, этот пакет поставляет Разработаны коллекции реализаций для использования в многопоточных контекстах: ConcurrentHashMap, ConcurrentSkipListMap, ConcurrentSkipListSet, CopyOnWriteArrayList и CopyOnWriteArraySet. Когда много тем Ожидается, что доступ к данному коллекции, ConcurrentHashMap является обычно предпочтительнее синхронизированного HashMap и ConcurrentSkipListMap обычно предпочтительнее синхронизированный TreeMap. CopyOnWriteArrayList предпочтительнее синхронизированный ArrayList, когда ожидаемое количество чтений и Обходы значительно превосходят по численности количество обновлений в списке.

0 голосов
/ 02 октября 2008

Если вы создаете класс коллекции, не делайте его потокобезопасным. Это довольно сложно сделать правильно (например, правильно и быстро), и проблемы для вашего потребителя, когда вы делаете это неправильно (heisenbugs), трудно отлаживать.

Вместо этого реализуйте один из API-интерфейсов Collection и используйте Collections.synchronizedCollection (yourCollectionInstance), чтобы получить поточно-ориентированную реализацию, если она им нужна.

Просто обратитесь к соответствующему методу Collections.synchronizedXXX в вашем классе javadoc; это прояснит, что вы учли безопасность нитей в своем дизайне и гарантировали, что у потребителя есть в своем распоряжении опция, обеспечивающая безопасность потоков.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...