Приведите Java код с ошибкой синхронизации: public class Counter{ private int c=0; public void inc(){ c++; } } — объясните проблему в многопоточном доступе и предложите несколько корректных вариантов реализации счётчика с высокой производительностью

8 Мая в 08:09
24 +1
0
Ответы
1
Ошибка (пример с вашей реализацией):
public class Counter {
private int c = 0;
public void inc() { c++; }
public int get() { return c; }
}
Проблема (кратко): операция c++c++c++ не атомарна — это чтение, инкремент и запись. При двух потоках возможна интерливинг: оба читают c=0c=0c=0, оба вычисляют 111 и оба записывают 111 — в итоге получаем 111 вместо ожидаемых 222. volatile здесь не поможет, потому что не делает сложные операции атомарными.
Корректные варианты реализации (с упором на производительность):
1) Синхронизированный счётчик (корректно, но менее производительно при высокой конкуренции):
public class CounterSync {
private int c = 0;
public synchronized void inc() { c++; }
public synchronized int get() { return c; }
}
2) AtomicInteger (CAS — хорош для умеренной конкуренции):
import java.util.concurrent.atomic.AtomicInteger;
public class CounterAtomic {
private final AtomicInteger c = new AtomicInteger(0);
public void inc() { c.incrementAndGet(); }
public int get() { return c.get(); }
}
3) LongAdder (лучше при высокой конкуренции по операциям инкремента; чтение — суммирование шардов):
import java.util.concurrent.atomic.LongAdder;
public class CounterLongAdder {
private final LongAdder c = new LongAdder();
public void inc() { c.increment(); }
public long get() { return c.sum(); }
}
4) AtomicLong / LongAccumulator (если нужен long или сложная функция агрегации):
import java.util.concurrent.atomic.AtomicLong;
public class CounterAtomicLong {
private final AtomicLong c = new AtomicLong(0L);
public void inc() { c.incrementAndGet(); }
public long get() { return c.get(); }
}
Краткие рекомендации:
- Для низкой конкуренции — AtomicInteger/AtomicLong (CAS) обычно достаточно.
- Для очень высокой конкуренции по инкременту — LongAdder даёт лучшую пропускную способность.
- Для атомарных комплексных операций используйте синхронизацию или специализированные механизмы (CAS-loop, StampedLock и т.п.).
8 Мая в 08:20
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир