разве там какая-либо причина не состоит в том, чтобы реализовать блокировку конфиденциально для создания этого ориентированным на многопотоковое исполнение?
Это зависит. Ваша цель состоит в том, чтобы записать класс набора, к которому получают доступ несколько потоков? Если так, сделайте это ориентированным на многопотоковое исполнение. В противном случае не тратьте впустую свое время. Такого рода вещь - то, что люди отсылают к тому, когда они говорят о 'преждевременной оптимизации'
Решите проблемы, которые Вы имеете. Не пытайтесь решить будущие проблемы, что Вы думаете, что у Вас может быть несколько лет в будущем, потому что Вы не видите будущее, и Вы неизменно будете неправы.
Примечание: Все еще необходимо написать код удобным в сопровождении способом, таким, что, если бы действительно необходимо было приехать и добавить блокировку к набору, это не было бы ужасно твердо. Моя точка, "не реализуют опции, в которых Вы не нуждаетесь и не будете использовать"
Вот хорошее начало.
ориентированный на многопотоковое исполнение словарь
Но Вы заметите потерю одной из замечательных особенностей наборов - перечисление. Вы не можете ориентированный на многопотоковое исполнение перечислитель, это просто не действительно выполнимо, если Вы не реализуете свой собственный перечислитель, который сдерживает блокировку экземпляра к самому набору. Я подозревал бы, что это вызовет главные узкие места и потенциальные мертвые блокировки.
Я соглашаюсь, что отъезд его до потребителя является правильным подходом. Если предоставляет потребителю намного больше гибкости относительно того, синхронизируется ли экземпляр Набора на, или другой объект синхронизируется на. Например, если бы у Вас было два списка, что оба должны были быть обновлены, могло бы иметь смысл иметь их в единственном sychronized блоке с помощью единственной блокировки.
При создании класса набора не делайте его ориентированным на многопотоковое исполнение. Довольно трудно сделать правильно (например, корректный и быстрый), и проблемы для Вашего потребителя, когда Вы делаете это неправильно (heisenbugs), трудно отладить.
В земельном участке реализуйте одни из API Набора и используйте Collections.synchronizedCollection(yourCollectionInstance) для получения ориентированной на многопотоковое исполнение реализации, если им нужен он.
Просто обратитесь к соответствующему методу Collections.synchronizedXXX в своем классе javadoc; это ясно даст понять, что Вы рассмотрели потокобезопасность в своем дизайне и удостоверились, что у потребителя есть ориентированная на многопотоковое исполнение опция в его распоряжении.
Это лишило бы возможности на, одновременно получают доступ к набору от нескольких потоков, даже если Вы знаете, что элемент, которого Вы касаетесь, не используется никем больше.
Примером был бы набор с основанным на целом числе индексным средством доступа. Каждый поток мог бы знать из его идентификатора, которые индексируют значения, к которым он может получить доступ, не вызывая беспокойство о грязных чтениях/записях.
Другой случай, где Вы поразили бы ненужную производительность, будет, когда данные будут только считаны с набора и не записаны в.
Действительно серьезное основание НЕ сделать Ваш набор ориентированным на многопотоковое исполнение для улучшенной производительности единственного потока. Пример: ArrayList по Вектору. Задержка потокобезопасности вызывающей стороне позволяет несинхронизируемому варианту использования оптимизировать путем предотвращения блокировки.
Действительно серьезное основание сделать Ваш набор ориентированным на многопотоковое исполнение для улучшенной многопоточной производительности. Пример: ConcurrentHashMap по HashMap. Поскольку CHM усваивает многопоточные проблемы, он может чередовать блокировку для большего параллельного доступа эффективнее, чем внешняя синхронизация.
В основном разработайте свой набор как ориентированный на многопотоковое исполнение с блокировкой, реализованной в двух методах Вашего класса: блокировка () и разблокировала (). Назовите их где угодно необходимыми, но оставьте их пустыми. Затем разделите свой набор на подклассы, реализовав блокировку () и разблокируйте () методы. Два класса за цену одной.
Создание ориентированного на многопотоковое исполнение набора - то, что уничтожило классы Вектора и Хеш-таблицы Java. Для клиента намного легче перенести его в ориентированную на многопотоковое исполнение обертку, как ранее предложено, или синхронизировать доступ к данным на подмножестве методов, чем получить удар синхронизации каждый раз, когда к классу получают доступ. Едва ли кто-то использует Вектор или Хеш-таблицу, и если они делают, над ними смеются, потому что их замены (ArrayList и HashMap) являются мирами быстрее. Который неудачен, поскольку я (происхождение из среды C++) очень предпочитаю "Векторное" имя (STL), но ArrayList приходит надолго.
Основная причина для не создания этого ориентированным на многопотоковое исполнение является производительностью. Ориентированный на многопотоковое исполнение код может составить 100 с времен медленнее, чем небезопасный код, поэтому если Вы, клиент не хочет функцию, это - довольно большие отходы.
Если я ищу класс набора, и мне нужны ориентированные на многопотоковое исполнение возможности, и Ваш класс не имеет их, я сразу собираюсь пропустить к следующему предложению там видеть то, что они обеспечивают. Ваш набор не будет больше добираться моего внимания.
Отметьте "Если" вначале. Некоторые клиенты захотят это, некоторые не будут, и некоторые не будут заботиться. Если Вы собираетесь создать инструментарий для потребителей, то почему бы не предложить оба варианта? Тем путем я могу выбрать, какой использовать, но если я хочу ориентированный на многопотоковое исполнение, у Вас все еще есть мое внимание, и я не должен писать это сам.
Просто будьте ясны в своей документации, которые Ваш не делают ее ориентированной на многопотоковое исполнение и пропускают ее, или если для Вашего приложения Вы хотите ее ориентированный на многопотоковое исполнение, сделайте ее ориентированной на многопотоковое исполнение и обратите внимание на это в своей документации для нее. Единственное правило состоит в том, чтобы зарегистрировать его. Кроме этого, сделайте свой класс для Вас и если другие люди хотят использовать его, они могут.
Для Java необходимо оставить несинхронизируемым для скорости. Потребитель набора может перенестись в обертке синхронизации при желании.
Я лично оставил бы его до потребителей. Это сделает Ваш класс набора более универсальным.
Классы набора должны быть максимально быстро. Следовательно пропустите блокировки.
Код вызова будет знать, где блокировки лучше всего лежат, класс набора не делает. В худшем варианте развития событий приложение должно будет добавить дополнительную блокировку, означающую, что две блокировки происходят, заставляя это удвоиться, перфект совершил нападки.
Обратите внимание, что, при попытке сделать какой-либо класс ориентированным на многопотоковое исполнение, необходимо выбрать сценарии общего использования.
Например, в случае набора, просто делая все свойства и методы индивидуально ориентированными на многопотоковое исполнение не могло бы быть достаточно хорошим для потребителя, как чтение сначала количества, и затем цикличное выполнение, или подобный, не сделает много хорошего если количество, измененное после чтения его.