'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. 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. 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? . Please find the piece of code below: 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");
}
}
Solution 1:[1]
I not got the answer for this.It is giving wrong value because of "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.
Solution 2:[2]
++prevValue.count
changed the value
prevValue.count
: 1- after
++prevValue.count
newValue.count
,prevValue.count
: 2compareAndSet
failed, matched while loop conditionprevValue.count
: 2- after
++prevValue.count
newValue.count
,prevValue.count
: 3compareAndSet
success
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | nayak0765 |
Solution 2 | Confucius |