ealeon
ealeon

Reputation: 12452

Java: synchronization does not block if it changes

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

Answers (1)

Andreas
Andreas

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

Related Questions