volatile-счётчик обработанных сообщений теряет инкременты
Консьюмер считает обработанные сообщения для метрики:
public class MessageHandler {
private volatile int processed = 0;
public void onMessage(Message m) {
process(m);
processed++;
}
}
Один и тот же экземпляр обрабатывает сообщения в 8 потоках. За прогон каждый поток вызвал onMessage ровно 10 000 раз, исключений в логе нет. Какое значение processed увидит метрика по итогам прогона?
- Ровно 80 000: volatile делает все операции с переменной атомарными, включая инкремент
- Ровно 80 000: инкремент int укладывается в одну машинную инструкцию на 64-битной JVM
- Больше 80 000: часть инкрементов применится дважды из-за перечитывания устаревшего значения
- Скорее всего меньше 80 000: volatile даёт видимость, но не атомарность операции чтение-изменение-запись
