Это школьное задание, но мне действительно нужна помощь с этим. Я не могу за всю жизнь понять, почему две разные версии nextValue()
ведут себя по-другому - одно - это потокобезопасное, а другое - нет. Может ли кто-нибудь дать мне несколько указателей в правильном направлении?Безопасная резьба по сравнению с небезопасными реализациями счетчика
Я включил обе версии в одном классе ниже, но, очевидно, они оба не присутствуют в коде ...
public class NumGenerator {
static final int MIN_VALUE = -256;
static final int MAX_VALUE = 255;
static final int INITIAL_VALUE = MIN_VALUE -1;
private final AtomicInteger counter = new AtomicInteger(INITIAL_VALUE);
private final AtomicInteger resetCounter = new AtomicInteger(0);
private final Object lock = new Object();
// Thread safe
public int nextValue() {
int next = counter.incrementAndGet();
if (next > MAX_VALUE) {
synchronized (lock) {
next = counter.incrementAndGet();
if (next> MAX_VALUE) {
counter.set(MIN_VALUE);
resetCounter.incrementAndGet();
next = MIN_VALUE;
}
}
}
return next;
}
// Non thread safe
public int nextValue() {
int next = counter.incrementAndGet();
if (next > MAX_VALUE) {
synchronized (lock) {
int i = counter.get();
if (i > MAX_VALUE) {
counter.set(INITIAL_VALUE);
resetCounter.incrementAndGet();
}
next = counter.incrementAndGet();
}
}
return next;
}
}
Логика обоих кодов выглядит по-другому. IMHO, обе функции являются потокобезопасными. Однако, как уже упоминалось, обе функции могут возвращать другой результат, чем ожидалось. –
Вы правы, они возвращают разные выходы ... но почему? Для меня они выглядят функционально одинаковыми. Что мне не хватает? – BadCash
'counter.get();' и 'counter.incrementAndGet(); 'разные. Таким образом, вы получите другой вывод – iNan