Очевидно, что volatile
недостаточно силен для реализации счетчика, потому что он не гарантирует атомарность.Однако, если число операций чтения значительно превышает количество, вы можете комбинировать внутреннюю блокировку и переменные переменные, чтобы снизить затраты на общий путь кода.Проверьте это,
public class Counter {
@GuardedBy("this") private volatile int value;
public int getValue() { return value; }
public synchronized int increment() {
return value++;
}
}
Код использует синхронизированный, чтобы гарантировать, что операция приращения является атомарной и использует volatile, чтобы гарантировать видимость текущего результата.Если обновления происходят нечасто, этот подход может работать лучше, поскольку издержки на пути чтения составляют только volatile
чтение, что, как правило, дешевле, чем получение блокировки.