The following code is supposed to prevent Data Racing by using the synchronized method on common. But for some reason the output is always 19915-19980. Shouldn’t it be 20000 if it was not data racing?
public class SyncVarDataRace extends Thread {
private static int common = 0;
public void run(){
synchronized((Integer)common){
int local = common;
local+=1;
common = local;
}
}
public static void main(String[] args) throws InterruptedException {
SyncVarDataRace[] allThreads = new SyncVarDataRace[20000];
for(int i = 0; i < allThreads.length; i++){
allThreads[i] = new SyncVarDataRace();
}
for(SyncVarDataRace d: allThreads){
d.start();
}
for(SyncVarDataRace d: allThreads){
d.join();
}
System.out.println(common);
}
}
You are trying to synchronize on an auto-boxed object that will be a different object every time.
The whole point is to synchronize on the same object in each thread. Even if you made
commonbe anInteger, as soon as you assign it to another value, it would be a different object.You need to lock on a constant object instead. I would recommend defining a local Object that you can synchronize on:
It might be better in this specific case, you might consider using an
AtomicInteger. That allows you do something like the following without any synchronization.