Непрозрачный режим, полученный с помощью VarHandle getOpaque и setOpaque, добавляет ограничения по сравнению с обычным режимом, которые обеспечивают минимальную осведомленность о переменной, к которой осуществляется межпоточный доступ, когда все обращения используют непрозрачный (или более сильный) режим
[...]
Режим Release/Acquire (или RA) получается с помощью VarHandle setRelease, getAcquire и связанных с ним методов и добавляет «кумулятивное» ограничение причинности к непрозрачному режиму.
У нас в основном однопоточный путь кода, критичный к производительности. Мы хотим предоставить внутренний размер коллекции метрик (для Grafana), которые собираются другим потоком. Значение метрики не обязательно должно быть абсолютно актуальным — оно просто должно со временем стать видимым.
Чтобы избежать накладных расходов на изменчивые поля или синхронизированное чтение, мы используем подобную оболочку:
Код: Выделить всё
public class FastSizeMetric {
private long size;
private static final VarHandle SIZE_HANDLE;
static {
try {
SIZE_HANDLE = MethodHandles.lookup()
.findVarHandle(FastSizeMetric.class, "size", long.class);
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
// must be used while holding a lock (any lock/synchronized block will do it)
public void updateSize(final long newSize) {
size = newSize; // plain write
}
public long getSize() {
return (long) SIZE_HANDLE.getOpaque(this);
}
}
Код: Выделить всё
synchronized (jobId-related lock) {
// ... calculations ...
metric.updateSize(map.size());
// ... calculations ...
metric.updateSize(map.size());
// ... calculations ...
}
Вопросы:
- Дает ли выполнение простой записи внутри синхронизированного блока те же гарантии конечной видимости для другого потока, вызывающего getOpaque(), что и явный setOpaque()?
- Является ли "случайный" синхронизированный блок вокруг записи, достаточный для обеспечения возможной видимости непрозрачного чтения?
- Гарантируется ли такое поведение спецификацией Java Memory Model / VarHandle, или это просто деталь реализации, которая работает в текущих JDK?
- Можно ли на этот шаблон положиться в будущих версиях JDK, или нам действительно «повезет» сегодня?
Подробнее здесь: https://stackoverflow.com/questions/798 ... visibility
Мобильная версия