Не правильно работает потоко - безопасный счетчик CAS не блокирующий алгоритм
Пишу потокобезопасный счетчик . Когда тестирую и потоки идут сначала один , потом второй все правильно работает . Но когда потоки заходят одновременно в метод increment() , счетчик не правильно отрабатывает. Не понятна причина , я ведь использую atomic integer .
@ThreadSafe
public class CASCount {
private final AtomicReference<Integer> count = new AtomicReference<>(0);
private AtomicInteger oldValue = new AtomicInteger(0);
private AtomicInteger newValue = new AtomicInteger(0);
public void increment() {
do {
oldValue.set(count.get());
System.out.println(oldValue + " old");
if (oldValue.get() == -1) {
throw new UnsupportedOperationException("Count is not impl.");
}
newValue.incrementAndGet();
System.out.println(newValue + " new");
} while (!count.compareAndSet(oldValue.get(), newValue.get()));
}
public int get() {
int result = -1;
result = count.get();
if (result == -1) {
throw new UnsupportedOperationException("Count is not impl.");
}
return result;
}
}
@Test
public void whenUseCASCount() throws InterruptedException {
CASCount count = new CASCount();
Thread one = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("one");
count.increment();
}
});
Thread two = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("two");
count.increment();
}
});
one.start();
two.start();
one.join();
two.join();
assertThat(count.get(), is(10));
}
Ответы (1 шт):
Автор решения: Terasan
→ Ссылка
мое решение
private final AtomicReference count = new AtomicReference<>(0);
public void increment() {
int current, next;
do {
current = count.get();
next = current + 1;
} while (!count.compareAndSet(current, next));
}
public int get() {
return count.get();
}