Reputation: 12452
Related Java will synchronized block if changed?
public class TestConcurrentTwo {
public static void main(String[] args) {
class lock {
public Object lockObj = new Object();
int protectedValue = 0;
}
lock a = new lock();
Thread t = new Thread(() -> {
try {
synchronized (a.lockObj) {
System.out.println("from first block start");
System.out.println(a.protectedValue);
a.lockObj = new Object();
Thread.sleep(1000);
System.out.println(a.protectedValue);
System.out.println("from first block done");
}
} catch (InterruptedException x) {}
});
t.start();
try {
Thread.sleep(100);
} catch (InterruptedException x) {}
synchronized (a.lockObj) {
System.out.println("from second block start");
a.protectedValue++;
System.out.println("from second block done");
}
System.out.println(a.protectedValue);
}
}
OUTPUT:
from first block start
0
from second block start
from second block done
1
1
from first block done
In the related answer, they both hold the original reference so the second block should be blocked until the completion of the first.
However, second block indeed proceeded once a.lockObj
changed from first block. why?
Upvotes: 0
Views: 38
Reputation: 159086
You are creating two objects, so let's name them for our reference:
ObjA created in the field initializer
ObjB created in the line right before sleep(1000)
The synchronized (a.lockObj)
block in the thread is locking on ObjA.
Since you have sleep(100)
after starting the thread, the thread will have changed a.lockObj
to refer to ObjB by the time the main thread reaches its synchronized (a.lockObj)
block, so that will lock on a different object.
Being a different object, the code will not block.
Hint: The lock is on the object, not the reference variable.
Upvotes: 2