13

My question is if I have some code like the following -:

public class OuterClass{
   public class InnerClass{
          public synchronized methodA(){ /* does something */}
   }
}

now when multiple threads want to call the inner class method will they acquire a lock for the outer class object or for the inner class object and how does one modify the statement so that I synchronize access to the outer class object/

AnkitSablok
  • 3,021
  • 7
  • 35
  • 52
  • You asked pretty much the same Question a few days ago ... http://stackoverflow.com/questions/18798259/acquiring-inner-class-lock-using-outer-class-locks ... and my answer to that Question answers this one too. – Stephen C Sep 20 '13 at 07:22

3 Answers3

19

when multiple threads want to call the inner class method will they acquire a lock for the outer class object

No.

or for the inner class object

Yes.

and how does one modify the statement so that I synchronize access to the outer class object/

Add:

synchronized (OuterClass.this)
{
}

inside the method, but note that the inner lock is acquired before the outer lock, as the syntax should now suggest. A consistent locking order is essential to prevent deadlocks. You might prefer to acquire the outer lock first, in which case you should do this:

public void methodA()
{
    synchronized(OuterClass.this)
    {
        synchronized (this)
        {
            // ...
        }
    }
}

without a synchronized declaration on the method itself. Or if you only want the outer lock, do this:

public void methodA()
{
    synchronized(OuterClass.this)
    {
        // ...
    }
}
user207421
  • 305,947
  • 44
  • 307
  • 483
  • I don't think that is what the op wants - I think he just wants the outer class lock, not two locks. – assylias Sep 20 '13 at 07:16
  • 2
    @assylias Anybody's guess really, but I may as well cover all the possibilities. – user207421 Sep 20 '13 at 07:28
  • Then how does the code here ( https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html ) is ending up with a deadlock ? I mean the threads called on different objects so for deadlock to happen, aren't the synchronized methods should be locked on the same object ? – stdout Apr 02 '16 at 19:57
  • 1
    @zgulser Your citation has nothing to do with inner classes or this question. It is a simple case of two threads acquiring locks in different orders, which I have already mentioned as being essential to avoid. – user207421 May 03 '16 at 10:30
  • @EJP I think the stuff I posted in the link is not that "unrelated". There's a nested class with synchronized methods and I just wondered how synchronization applies here, as the class is nested ( and yes, static ). Just like the inner classes have or something different ? Because for deadlock to occur, it should lock the methods on different objects, not on a class itself. Hope I'm clear now. – stdout May 03 '16 at 13:01
  • 1
    @zgulser Inner class objects have outer objects: static class objects do not. For deadlock to occur you need two locks acquired in different orders. Whether object locks or class locks has nothing to do with it. – user207421 May 18 '16 at 18:47
  • @EJP Finally got the point. bowback was being called on the bower. I sort of ignored it and thought it was called on "this". That's why I kept asking whether the lock is class level or not, to sort of trying the code meaningfull. Thanks for the insistent support. – stdout May 18 '16 at 22:30
4

It will use the this of the immediately enclosing class so the inner class. You can use instead:

public void m() {
    synchronized(OuterClass.this) {
    }
 }
assylias
  • 321,522
  • 82
  • 660
  • 783
-1

Since you have made the inner class method as synchronized it won't lock the outer class object rather it will only lock the inner class method. To synchronize the outer class as stated earlier it can done as shown below

public void methA()
{

synchronized(OuterClass.this)

{`enter code here`
        // ...
    }
}
ian0411
  • 4,115
  • 3
  • 25
  • 33