Не правильно работает потоко - безопасный счетчик 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();
}
→ Ссылка