I start learning some java concurrency concept ans put in use.
But one of this piece of code is beyond my understanding.
public class Count {
private int count = 0;
public synchronized void setCount(int count) {
this.count = count;
}
public synchronized int getCount() {
return count;
}
}
class CountRunner extends Thread {
Count count;
public CountRunner(Count count) {
this.count = count;
}
public void run() {
for (int i = 1; i <= 1000; i++) {
count.setCount(count.getCount() + 1);
}
}
}
class TestCount {
public static void main(String[] args) throws Exception {
Count count = new Count();
CountRunner runnerA = new CountRunner(count);
CountRunner runnerB = new CountRunner(count);
runnerA.start();
runnerB.start();
runnerA.join(); //join statement here
runnerB.join();
System.out.println("count.getCount = " + count.getCount());
}
}
Question: 1. The result is a little less than 2000 for many times, why ? 2. if delete 2 join() statement, why count.getCount = 451,even less ? 3. i think there will be no effect of deleting the join() statements, because i already have Synchronized method to lock one object to one thread each time ? So, What's the point of using Synchronized and join() ?
It is pretty simple. You call the setCount method by calling the getCount + 1. Before entering the method, the runtime evaluates the getCount (synchronized), but you don’t hold the lock when leaving getCount and entering setCount and other threads can enter an call getCount. So every now and then two (or more depending on how many threads you create) threads will have the same value in the getCount. Imagine thread A enters and receives the value 1 in getCount. The runtime yields it’s execution to tread B which calls getCount and receives the same value 1. Thread B sets the value to 1 and makes another 50 runs, so your count would be 50 at that stage. The runtime yields the execution to thread A which calls setCount with 1 (remember it didn’t manage to call setCount and yielded it’s exec). Now A sets the value to 1 (which is wrong).
Change you run implementation like this: