Hossein Margani
Hossein Margani

Reputation: 1056

Nested synchronized keyword

I have this code in Java:

    public void doSomeThing() {
        synchronized (this) {
            doSomeThingElse();
        }
    }
    public void doSomeThingElse() {
        synchronized (this) {
            // do something else
        }
    }

Can this code block? I mean, Can this code wait for ever?

Upvotes: 44

Views: 9890

Answers (6)

Kissaki
Kissaki

Reputation: 9237

As the java documentation describes for Reentrant locking:

a thread can acquire a lock that it already owns

The second synchronized block is using the same lock and thus will always be useable as the lock has already been aquired in the outer method.

No, there will not be a deadlock.

Upvotes: 58

fastcodejava
fastcodejava

Reputation: 41117

If a thread owns the lock on this, it will go into other synchronized methods/block like hot knife in butter.

Upvotes: 8

aNish
aNish

Reputation: 1077

You have already taken the monitor lock in the first synchronized. You should always ensure that the concurrency design does not make the performance impact huge.

One way to ensure this is by synchronizing only the required statements/code.

Let's say now your code will look something like this.

public void doSomeThing()
 {
  synchronized (this) 
   {             
    synchronized (this) 
     {             
      // do something else         
     }           
   }     
 }

Whereas this is what is required

public void doSomeThing()
     {
       doSomeThingElse();     
     }
public void doSomeThingElse()
{
 synchronized (this) 
         {             
          // do something else         
         }
}

Upvotes: 0

fluminis
fluminis

Reputation: 4089

The synchronized use in both case this so if the synchronized block in doSomeThing run, you allready have the lock so you can execute the doSomeThingElse method.

If your code is so simple, it is equivalent to :

public synchronized void doSomeThing() {
    doSomeThingElse();
}
public synchronized void doSomeThingElse() {
    // do something else
}

Upvotes: 0

Dennis
Dennis

Reputation: 3731

In a synchronized block you can re-aquire a lock that you already own. The lock provider (this) will be acquired by the first thread to enter doSomething(). Then in the doSomethingElse() method it will re-aquire it.

The reason to do this? Well there is nothing to say that there is not some other thread entering doSomethingElse from elsewhere. This will prevent any code from executing the block in doSomething() until the thread in doSomethingElse() has released "this".

Edit BTW it can of course block... and it will block any thread that does not own the synchronization object from executing. However it will not (as posted) deadlock.

Upvotes: 3

Gursel Koca
Gursel Koca

Reputation: 21300

Lock already obtanied by the thread executing doSomething method, therefore this thread can execute doSomethingElse method.

You need two lock object to create a deadlock situation. In your case, there is only one, therefore it is impossible to create a deadlock.

Upvotes: 1

Related Questions