Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a synchronized method from of a synchronized method, both of the same object [duplicate]

Why doesn't the code below lead to a deadlock? I mean after i call getNumber(.) the object of the class Test should be locked, so I shouldn't be able to access getNumber2(.).

class Test() {
    synchronized int getNumber(int i){
        return getNumber2(i);
    }

    synchronized int getNumber2(int i) {
        return i;
    }

    public static void main(String[] args) {
        System.out.println((new Test()).getNumber(100));
    }
}

Output:

100
like image 314
Yannick Wald Avatar asked Mar 04 '13 14:03

Yannick Wald


People also ask

Is it safe to call a synchronized method from another synchronized method?

Yes , we can call any number of synchronized method within any synchronized method , it will work as stack how normal method works because when we make any method as synchnonized then lock is over class and thread which owns this lock is running all these methods so there is mens of conflict..

Can two threads call two different synchronized methods of the same class?

First, it is not possible for two invocations of synchronized methods on the same object to interleave. When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

What will happen if a Synchronised method is called by two threads on different object instance simultaneously?

so the execution will not be not concurrent, both threads will execute one by one, when both the threads use the synchronized method on different objects, they will run concurrently.

Can two threads access a synchronized method at the same time?

Two threads cannot access the same synchronized method on the same object instance. One will get the lock and the other will block until the first thread leaves the method. In your example, instance methods are synchronized on the object that contains them.


2 Answers

This is because the lock is re-entrant, meaning that it can be acquired multiple times by the same thread.

From the Java tutorial:

Reentrant Synchronization

Recall that a thread cannot acquire a lock owned by another thread. But a thread can acquire a lock that it already owns. Allowing a thread to acquire the same lock more than once enables reentrant synchronization. This describes a situation where synchronized code, directly or indirectly, invokes a method that also contains synchronized code, and both sets of code use the same lock. Without reentrant synchronization, synchronized code would have to take many additional precautions to avoid having a thread cause itself to block.

The relevant part of the JLS is §17.1. Synchronization:

The Java programming language provides multiple mechanisms for communicating between threads. The most basic of these methods is synchronization, which is implemented using monitors. Each object in Java is associated with a monitor, which a thread can lock or unlock. Only one thread at a time may hold a lock on a monitor. Any other threads attempting to lock that monitor are blocked until they can obtain a lock on that monitor. A thread t may lock a particular monitor multiple times; each unlock reverses the effect of one lock operation.

like image 122
NPE Avatar answered Nov 08 '22 05:11

NPE


It doesn't lead to a deadlock because when a thread enter a synchronized method, what it does is checking that it has a lock on this, then if it doesn't, it waits until it can have the lock and get it.

When the thread enters the second synchonized method in your case, it already has the lock on the this object, so it can enter the method without blocking.

like image 41
Cyrille Ka Avatar answered Nov 08 '22 07:11

Cyrille Ka