Какое наименьшее значение используется в байтах для блокировки монитора?

Чтобы использовать встроенную блокировку в 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 для монитора просто создайте объекты для набора значений.

Это ОО путь.

Другие вопросы по тегам