I am trying to understand "synchronized block" in Java. I have written very basic code to see what happens if I lock and change the object in thread_1 and access to it from another thread_2 (race condition) via another method. But I am in trouble to understand the behaviour because I was expecting Thread_1 would change value first and then Thread_2 would access the new value but the result was not as I expected.
public class Example {
public static void main(String[] args){
final Counter counter = new Counter();
Thread threadA = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("THREAD_1_START");
counter.add(1);
System.out.println("THREAD_1_END");
}
});
Thread threadB = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("THREAD_2_START");
System.out.println("GET_A_BY_THREAD_2:"+counter.getA(2));
System.out.println("THREAD_2_END");
}
});
threadA.start();
threadB.start();
}
}
public class Counter{
String A = "NONE";
public void add(long value){
synchronized (A) {
System.out.println("LOCKED_BY_"+value);
for(int i = 0; i < 1000000000; i++ ){}
setA("THREAD_"+value);
System.out.println("GET_A_BY_THREAD:"+getA(value));
}
}
public void setA(String A){
System.out.println("Counter.setA()");
this.A = A;
System.out.println("Counter.setA()_end");
}
public String getA(long value){
System.out.println("Counter.getA()_BY_"+value);
return this.A;
}
}
The Output is:
THREAD_1_START
THREAD_2_START
LOCKED_BY_1
Counter.getA()_BY_2
GET_A_BY_THREAD_2:NONE
THREAD_2_END
Counter.setA()
Counter.setA()_end
Counter.getA()_BY_1
GET_A_BY_THREAD:THREAD_1
THREAD_1_END
Thread_1 locks the "A" string object and changes it but Thread_2 can read the value before it changes. When "A" is in lock, how can thread_2 can access the "A" object?