简体   繁体   English

AtomicReference 无法避免 java 多线程中的竞争条件

[英]AtomicReference not working to avoid race condition in java multi threading

I have a "User.java" class that has Integer variable count initially set to 0. In another class "ThreadDemo.java" I have set the User object in AtomicReference.我有一个“User.java”class,它的 Integer 变量计数最初设置为 0。在另一个 class“ThreadDemo.java”中,我在 AtomicReference 中设置了用户 object。 This "userRef" object is shared by "1000" threads and in each thread I am incrementing the "count" value by 1. But here i am not getting expected answer 1000.Each time I execute "count" variable gives different value like 1000,1002 etc.. But if i try to use synchronization or AtomicInteger then it works.这个“userRef”object 由“1000”个线程共享,在每个线程中我将“计数”值递增 1。但在这里我没有得到预期的答案 1000。每次我执行“计数”变量都会给出不同的值,如 1000 ,1002 等。但是如果我尝试使用同步或 AtomicInteger 那么它就可以工作。 So my question is,am i using AtomicReference concept properly to resolve race condition in this case.If yes, then Why I it is failing in this case?所以我的问题是,在这种情况下我是否正确使用 AtomicReference 概念来解决竞争条件。如果是,那么为什么我在这种情况下失败了? . . Please find the piece of code below: User.java:-请在下面找到这段代码:User.java:-

public class User {

     public Integer count=0; 

} 

ThreadDemo.java:- 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");
    }
}

I not got the answer for this.It is giving wrong value because of "newValue.count = ++prevValue.count". 我没有得到答案。由于“ newValue.count = ++ prevValue.count”,它给出了错误的值。 Here the pre increment operator chances the value of "prevValue"., Instead write this statement as "newValue.count = prevValue.count+1".It works fine then. 在这里,预递增运算符的值是“ prevValue”的值。相反,应将此语句写为“ newValue.count = prevValue.count + 1”。这样就可以正常工作了。

++prevValue.count changed the value ++prevValue.count改变了值

  • prevValue.count : 1 prevValue.count :1
  • after ++prevValue.count++prevValue.count之后
  • newValue.count , prevValue.count : 2 newValue.count , prevValue.count : 2
  • compareAndSet failed, matched while loop condition compareAndSet失败,匹配 while 循环条件
  • prevValue.count : 2 prevValue.count :2
  • after ++prevValue.count++prevValue.count之后
  • newValue.count , prevValue.count : 3 newValue.count , prevValue.count : 3
  • compareAndSet success compareAndSet成功

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM