Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I synchronized two methods on the same class, can they run simultaneously?

People also ask

Can two threads access a two 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.

What will happen if a synchronized method is called by two threads?

No. If a object has synchronized instance methods then the Object itself is used a lock object for controlling the synchronization. Therefore all other instance methods need to wait until previous method call is completed.

Can a synchronized method call another synchronized method?

As an answer to what I would guess is the actual question: yes, the synchronized keyword uses recursive locks; you can safely call a synchronized method from another synchronized method.

Can two threads call two different synchronized instance methods of an object?

No. If a object has synchronized instance methods then the Object itself is used a lock object for controlling the synchronization. Therefore all other instance methods need to wait until previous method call is completed.


Both methods lock the same monitor. Therefore, you can't simultaneously execute them on the same object from different threads (one of the two methods will block until the other is finished).


In the example methodA and methodB are instance methods (as opposed to static methods). Putting synchronized on an instance method means that the thread has to acquire the lock (the "intrinsic lock") on the object instance that the method is called on before the thread can start executing any code in that method.

If you have two different instance methods marked synchronized and different threads are calling those methods concurrently on the same object, those threads will be contending for the same lock. Once one thread gets the lock all other threads are shut out of all synchronized instance methods on that object.

In order for the two methods to run concurrently they would have to use different locks, like this:

class A {
    private final Object lockA = new Object();
    private final Object lockB = new Object();

    public void methodA() {
        synchronized(lockA) {
            //method A
        }
    }

    public void methodB() {
        synchronized(lockB) {
            //method B
        }
    }
}

where the synchronized block syntax allows specifying a specific object that the executing thread needs to acquire the intrinsic lock on in order to enter the block.

The important thing to understand is that even though we are putting a "synchronized" keyword on individual methods, the core concept is the intrinsic lock behind the scenes.

Here is how the Java tutorial describes the relationship:

Synchronization is built around an internal entity known as the intrinsic lock or monitor lock. (The API specification often refers to this entity simply as a "monitor.") Intrinsic locks play a role in both aspects of synchronization: enforcing exclusive access to an object's state and establishing happens-before relationships that are essential to visibility.

Every object has an intrinsic lock associated with it. By convention, a thread that needs exclusive and consistent access to an object's fields has to acquire the object's intrinsic lock before accessing them, and then release the intrinsic lock when it's done with them. A thread is said to own the intrinsic lock between the time it has acquired the lock and released the lock. As long as a thread owns an intrinsic lock, no other thread can acquire the same lock. The other thread will block when it attempts to acquire the lock.

The purpose of locking is to protect shared data. You would use separate locks as shown in the example code above only if each lock protected different data members.


Java Thread acquires an object level lock when it enters into an instance synchronized java method and acquires a class level lock when it enters into static synchronized java method.

In your case, the methods(instance) are of same class. So when ever a thread enters into java synchronized method or block it acquires a lock(the object on which the method is called). So other method cannot be called at the same time on the same object until the first method is completed and lock(on object) is released.


In your case you synchronized two method on the same instance of class. So, these two methods can't run simultaneously on different thread of the same instance of class A. But they can on different class A instances.

class A {
    public synchronized void methodA() {
        //method A
    }
}

is the same as:

class A {
    public void methodA() {
        synchronized(this){
            // code of method A
        }
    }
}