2

Considering the following code snippet:

 Object bar1  = new ... ; 
 Object bar2 = new ... ; 


 Object foo = (either bar1 or bar2) ; 

Now, foo can be either bar1 or bar2 at various times of the programs. I just wanted to check that synchronized(foo) will lock the corresponding bar1 or bar2. This seems like the most likely scenario given that objects aren't copied in Java. Is this correct?

user1018513
  • 1,682
  • 1
  • 20
  • 42

3 Answers3

6
Object bar1 = new Object();
Object foo = bar1;
synchronized(foo) {
    ...
}

will lock on foo==bar1.

However this is a weird and error-prone construct. For example:

  • Thread 1 arrives in your method and foo == bar1
  • Thread 1 arrives in the synchronized block and locks on bar1
  • Thread 2 arrives in your method and foo == bar2
  • Thread 2 arrives in the synchronized block and locks on bar2

Now you have 2 threads running your synchronized block concurrently. I can't really find a reason why you would want that. And if you do, then the block should probably not be synchronized and you should use a different locking strategy.

See also this related post.

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • 4
    +1 In general its a bad idea to synchronize on anything but a `final` field. If `bar1` or `bar2` need to be synchronized it should be synchronized internally. – Peter Lawrey Aug 21 '12 at 10:46
2

Yes. You're not synchronising on the reference, but rather the underlying object.

Each object has an associated monitor, and it's this that you're locking on when you use synchronized. From here:

In the Java virtual machine, every object and class is logically associated with a monitor. For objects, the associated monitor protects the object's instance variable. For classes, the monitor protects the class's class variables

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
2

Yes, it will lock on whichever object foo is pointing at. However, I stronly suggest you make foo final to avoid something like this:

Object foo = bar1;
synchronized(foo) {
   foo = bar2;
}

because it will cause havok with several threads seeing different locks. See also this question: Locking on a mutable object - Why is it considered a bad practice?

Community
  • 1
  • 1
Tudor
  • 61,523
  • 12
  • 102
  • 142