Reputation: 869
I was brushing my multi-threading basics. To understand synchronization i created following program-
package thread;
public class SynchronizedCounter implements Runnable{
private static int counter = 0;
public void run() {
while(counter < 10) {
synchronized (SynchronizedCounter.class) {
System.out.println(Thread.currentThread().getName() + " :: reads ## " + counter);
counter++;
System.out.println(Thread.currentThread().getName() + " :: updated value ## " + counter);
}
}
}
public static void main(String[] args) {
Thread[] threads = new Thread[5];
for(int i = 0; i < threads.length; i++) {
threads[i] = new Thread(new SynchronizedCounter(), "Thread-" + i);
threads[i].start();
}
for(int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Now when i executed, got this result:
Thread-0 :: reads --> 0
Thread-0 :: updated value --> 1
Thread-3 :: reads --> 1
Thread-3 :: updated value --> 2
Thread-0 :: reads --> 2
Thread-0 :: updated value --> 3
Thread-0 :: reads --> 3
Thread-0 :: updated value --> 4
Thread-0 :: reads --> 4
Thread-0 :: updated value --> 5
Thread-0 :: reads --> 5
Thread-0 :: updated value --> 6
Thread-0 :: reads --> 6
Thread-0 :: updated value --> 7
Thread-0 :: reads --> 7
Thread-0 :: updated value --> 8
Thread-0 :: reads --> 8
Thread-0 :: updated value --> 9
Thread-0 :: reads --> 9
Thread-0 :: updated value --> 10
Thread-1 :: reads --> 10
Thread-1 :: updated value --> 11
Thread-2 :: reads --> 11
Thread-2 :: updated value --> 12
Thread-4 :: reads --> 12
Thread-4 :: updated value --> 13
Thread-3 :: reads --> 13
Thread-3 :: updated value --> 14
Everything looks good but i could not understand why value of "counter" is going beyond 10. How while loop passing even though value is 13 or 14 which is more than 10. I understand that when control tries to enter while it may read different value and when it reaches to print it first time i.e. ":: reads -->". But ideally any thread should increase this value to 10. Please help me to understand where i am missing.
Thank you!!
Upvotes: 1
Views: 33
Reputation: 2446
Because the synchronized (SynchronizedCounter.class) is in the while loop. Imagine counter hits 9. All the threads can still enter the while block, and then one will run, incrementing counter to 10. It will exit the synchronized block, allowing another thread to run, incrementing counter to 11. This goes on for each of the threads, so counter will hit 14. Then the next time through the while loop, the counter < 10 test will fail and they'll all return from run(), thus exiting.
I'd guess another counter < 10 test within the synchronized block would fix it.
Upvotes: 3