AtomicReference не работает, чтобы избежать состояния гонки в многопоточности Java

У меня есть класс "User.java", в котором счетчик переменных Integer изначально установлен на 0. В другом классе "ThreadDemo.java" я установил объект User в AtomicReference. Этот объект "userRef" совместно используется потоками "1000", и в каждом потоке я увеличиваю значение "count" на 1. Но здесь я не получаю ожидаемый ответ 1000. Каждый раз, когда я выполняю переменную "count", выдается другое значение, например 1000,1002 и т.д.. Но если я пытаюсь использовать синхронизацию или AtomicInteger, то это работает. Поэтому мой вопрос заключается в том, правильно ли я использую концепцию AtomicReference для разрешения состояния гонки в этом случае. Если да, то почему в этом случае происходит сбой?, Пожалуйста, найдите фрагмент кода ниже: User.java:-

public class User {

     public Integer count=0; 

} 

ThreadDemo.java:-

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

public class ThreadDemo {

    static AtomicReference<User> userRef = new AtomicReference<User>(new User());

    public static void main(final String[] arguments) throws InterruptedException {

        System.out.println("main thread started");

        List<Thread> listThread = new ArrayList<>();

        for (int i = 1; i <= 1000; i++) {
            listThread.add(new Thread() {
                @Override
                public void run() {

                    boolean flag = false;

                    while (!flag) {
                        User prevValue = userRef.get();
                        User newValue = new User();
                        newValue.count = ++prevValue.count;
                        flag = userRef.compareAndSet(prevValue, newValue);
                    }

                }
            });
        }

        for (Thread t : listThread) {
            t.start();
        }

        for (Thread t : listThread) { 
            t.join();
        }

        System.out.println("user count:" + userRef.get().count);
        System.out.println("main thread finished");
    }
}

2 ответа

Я не получил ответ для этого. Это дает неправильное значение из-за "newValue.count = ++prevValue.count". Здесь оператор предварительного увеличения может изменить значение "prevValue". Вместо этого напишите этот оператор как "newValue.count = prevValue.count+1". Тогда он работает нормально.

изменил значение

  • : 1
  • после
  • , : 2
  • не удалось, совпадение с условием цикла
  • : 2
  • после ++prevValue.count
  • newValue.count, prevValue.count: 3
  • compareAndSetуспех
Другие вопросы по тегам