Какое наименьшее значение используется в байтах для блокировки монитора?
Чтобы использовать встроенную блокировку в Java, вы делаете
Object o = new Object()
...
sychronized (o) {
...
}
Таким образом, одному монитору уже требуется один объект, то есть 8 байтов или 16 байтов для 64-битных (или 12 байтов для сжатых операций и 64-битных).
Теперь предположим, что вы хотите использовать множество этих мониторов, например, для массива, который можно синхронизировать в определенных областях и который имеет лучший параллелизм (основанный на входе), чем Collections.synchronizedList
, Тогда какой самый эффективный способ реализовать это? Можно ли как-то использовать 2 вложенных замка для 4 записей или 3 для 8 и т. Д.? Или я мог бы использовать "один замок на поток", например, в ConcurrentHashMap<array_index, lock>
?
2 ответа
В зависимости от шаблонов доступа, вы можете увеличить параллелизм с меньшим количеством блокировок, сегментируя структуру данных и используя одну встроенную блокировку для защиты нескольких элементов. Этот метод используется в некоторых параллельных коллекциях, представленных в java.util.concurrent
пакет.
"Могу ли я как-то использовать 2 вложенных замка для 4 записей или 3 для 8 и т. Д.?" Похоже, вы планируете обрабатывать каждую блокировку как бит в индексе входа: если бит установлен, получить блокировку; если понятно, пропустите. Это не сработает. Подумайте об индексе 0. Блокировки не будут получены, и у вас не будет контроля параллелизма.
Вы можете заставить его "работать", удваивая количество блокировок (для каждого бита есть "установленная" и "чистая" блокировка), но это все равно плохая идея, потому что вы теряете блокировки и получаете действительно плохой параллелизм. Внешний замок будет охранять половину записей. Любые вложенные блокировки, полученные впоследствии, будут бесполезны, потому что другие потоки уже исключены из этого сегмента.
Это возвращает вас к сегментации ваших данных, с одной блокировкой на сегмент, как java.util.concurrency
делает.
Чтобы получить монитор, вам нужен объект, поэтому, чтобы получить функциональность, к которой вы стремитесь, т. Е. Блокировать набор примитивных значений, вам нужен объект для этого набора.
Вместо того, чтобы создавать массив значений и рассматривать блоки значений как набор, с отдельным Object
для монитора просто создайте объекты для набора значений.
Это ОО путь.