Общее правило не существует, оно зависит от компромисса между уровнем параллелизма и потреблением памяти.Striped
JavaDoc частично объясняет это:
Полосатый Lock/Semaphore/ReadWriteLock
.Это предлагает базовое чередование блокировок, подобное ConcurrentHashMap
, в многократно используемой форме и расширяет его для семафоров и блокировок чтения-записи. Концептуально чередование блокировок - это метод разделения блокировки на несколько полос, увеличения степени детализации одного блокирования и обеспечения возможности независимых операций для блокировки разных полос и одновременного выполнения вместо создания конфликта для одной блокировки.
Гарантия, предоставляемая этим классом, заключается в том, что равные ключи ведут к одной и той же блокировке (или семафору), т. Е. Если key1.equals(key2)
, то striped.get(key1) == striped.get(key2)
(при условии, что Object.hashCode()
правильно реализовано для ключей).Обратите внимание, что если key1
не равно key2
, не гарантируется, что striped.get(key1) != striped.get(key2)
;тем не менее элементы могут быть сопоставлены с одним и тем же замком. Чем меньше количество полос, тем выше вероятность этого.
...
До этого класса можно было бы испытать желание использовать Map<K, Lock>
где K
представляет задачу. Это максимизирует параллелизм за счет сопоставления каждого уникального ключа с уникальной блокировкой, а также максимизирует использование памяти.С другой стороны, можно использовать одну блокировку для всех задач, что минимизирует использование памяти, но также минимизирует параллелизм.Вместо выбора любого из этих экстремумов Striped
позволяет пользователю торговать между необходимым параллелизмом и объемом памяти. Например, если набор задач привязан к процессору, можно легко создать очень компактные Striped<Lock> of availableProcessors() * 4
полосы.вместо, возможно, тысяч блокировок, которые могут быть созданы в структуре Map<K, Lock>
.