I am learning Thread Safe. I wrote an example and got a question.
First, my main() function is the same:
public class ThreadSafe {
public static void main(String[] args) {
System.out.println("Thread Safe");
SafeSharedRunnable r = new SafeSharedRunnable();
// Access the same resource
Thread tA = new Thread(r);
Thread tB = new Thread(r);
Thread tC = new Thread(r);
Thread tD = new Thread(r);
tA.start();
tB.start();
tC.start();
tD.start();
}
}
Then I have two versions Runnable in which synchronized() are placed in different places, and thus, one version works and one doesn't.
The working version:
public class SafeSharedRunnable implements Runnable {
int count = 5;
@Override
public void run() {
// Thread Safe, must be outside of while(), why?
synchronized ("") {
while (count > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
System.out.println("Current value is: " + count--);
}
}
}
}
The correct result:
run:
Thread Safe
Current value is: 5
Current value is: 4
Current value is: 3
Current value is: 2
Current value is: 1
BUILD SUCCESSFUL (total time: 0 seconds)
The non-working version:
public class SafeSharedRunnable implements Runnable {
int count = 5;
@Override
public void run() {
while (count > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
// Thread Safe
synchronized ("") {
System.out.println("Current value is: " + count--);
}
}
}
}
The wrong result:
run:
Thread Safe
Current value is: 5
Current value is: 4
Current value is: 2
Current value is: 3
Current value is: 1
Current value is: 0
Current value is: -1
Current value is: -2
BUILD SUCCESSFUL (total time: 0 seconds)
As you can see, different places of different synchronized() blocks result in different results. In my understanding, the key resource conflict should happen on this line of code:
System.out.println("Current value is: " + count--);
But why I must place synchronized() outside of while() block? Does that mean I should synchronize all the codes that contains variable "count"? Thanks for your detailed explanation.
I don't think this is a duplicate to race condition question, because I am not asking any general knowledge about multi-threading. Instead this is a detailed question about how multi threads enter a code flow.