Подтвердить что ты не робот

Синхронизация по локальной переменной

Я заметил странную конструкцию в ConcurrentHashMap compute и computeIfAbsent методах:

Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
  //...
}

Какова точка синхронизации на локальном объекте, учитывая, что JIT, скорее всего, будет рассматривать его как не-op?

4b9b3361

Ответ 1

Сразу после того, как код приобрел монитор объектов, ссылка на объект хранится в tab, который является глобально видимым массивом узлов, которые составляют содержимое ConcurrentHashMap:

Node<K,V> r = new ReservationNode<K,V>();
synchronized (r) {
    if (casTabAt(tab, i, null, r)) {

В этот момент другие потоки, выполняющие другие методы модификации в одном и том же ConcurrentHashMap, могут столкнуться с этим неполным node при обходе глобального массива, другими словами, ссылка Node сбежала.

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

Его как "приоритетная синхронизация". Создатель синхронизируется в точке, где ссылка еще не была экранирована, поэтому она будет успешной, пока в точке, где выполняется эта ссылка, все остальные потоки должны будут ждать в маловероятном (но все же возможном) событии, к которому они обращаются точно это Node.