Почему поток, удерживающий блокировку, нуждается в ограждении захвата, чтобы наблюдать за своей собственной простой запиJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Почему поток, удерживающий блокировку, нуждается в ограждении захвата, чтобы наблюдать за своей собственной простой запи

Сообщение Anonymous »

Я реализую плоское объединение (исходная статья).
Когда объединитель применяет узел

Код: Выделить всё

class Node {
volatile Function action; //Used through its VarHandle
volatile Node next;
R item; // plain field

public void spItem(R item) { this.item = item; }
public R lpItem() { return item; }
void soAction(Function action) { ACTION.setRelease(this, action); }
boolean isApplied() { return ACTION.getAcquire(this) == null; }
}
, да:

Код: Выделить всё

//In a lock
Node curr;
curr.spItem(a.apply(item));  // plain write to result
curr.soAction(null);          // release signals completion of the write
Комбинаторы, не являющиеся объединителями, выполняют сбор данных в isApplied() перед чтением элемента, что имеет смысл, им необходимо синхронизироваться с выпуском объединителя.
Чего я не понимаю, так это того, почему объединителю также необходимо это ограничение получения при проверке своего собственного узла:

Код: Выделить всё

// Still inside the lock, after the combine loop
return ours.lpItem(); // plain read, why does this return a stale value from earlier?
Если я отброшу получение в isApplied(), только путь объединения вернет неправильное значение, однако с необъединителями все в порядке.
Мое нынешнее рассуждение состоит в том, что объединитель применяет свой собственный узел во время сканирования с простой записью в элемент, и поскольку это тот же поток, который читает его обратно, я ожидаю, что порядок программы будет гарантировать видимость без каких-либо ограничений. Есть ли что-то, что мне здесь не хватает?
Примечание: это проявляется только при высоком уровне параллелизма (более 32 потоков в моем тесте JMH). При меньшем числе потоков объединитель всегда считывает правильное значение.
Оказывается, это была ошибка корректности, а не проблема видимости. Узел объединителя может выйти за пределы отсечки maxCombinePass, если перед сканированием объединителя будет добавлено достаточно потоков, поэтому узел объединителя вообще не будет применен.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»