Do two synchronized methods execute simultaneously
Asked Answered
T

4

33

I have 4 methods (m1, m2, m3 and m4) in a class. Method m1, m2 and m3 are synchronized methods. Also, I have 4 threads t1, t2, t3 and t4 respectively.

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously? If not what would be the state of t2?

Trademark answered 1/7, 2010 at 17:6 Comment(0)
S
47

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously?

The synchronized keyword applies on object level, and only one thread can hold the lock of the object. So as long as you're talking about the same object, then no, t2 will wait for t1 to release the lock acquired when it entered m1.

The thread can however release the lock without returning from the method, by calling Object.wait().

If not, what would be the state of t2 ?

It would sit tight and wait for t1 to release the lock (return from the method or invoke Object.wait()). Specifically, it will be in a BLOCKED state.

Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait.

Sample code:

public class Test {

    public synchronized void m1() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public synchronized void m2() {
        try { Thread.sleep(2000); }
        catch (InterruptedException ie) {}
    }

    public static void main(String[] args) throws InterruptedException {
        final Test t = new Test();
        Thread t1 = new Thread() { public void run() { t.m1(); } };
        Thread t2 = new Thread() { public void run() { t.m2(); } };

        t1.start();
        Thread.sleep(500);

        t2.start();
        Thread.sleep(500);

        System.out.println(t2.getState());
    }
}

Output:

BLOCKED
Subroutine answered 1/7, 2010 at 17:8 Comment(3)
but if we do something like this then what? final Test tt1 = new Test(); final Test tt2 = new Test(); Thread t1 = new Thread() { public void run() { tt1.m1(); } }; Thread t2 = new Thread() { public void run() { tt2.m2(); } };Nevanevada
@Subroutine what happens in the case of synchronized code blocks (not methods). can two thread access two different synchronized code blocks of the same object concurrently?Bechtel
Depends on what you synchronize on. If you do synchronized(this) then the exact same rules apply.Subroutine
M
11

If the methods are synchronized on the same monitor, then they cannot execute simultaneously in different threads. When the second thread comes to the monitor entry (the start of the synchronized method in this case), it will block until the first thread releases the monitor.

The actual state of the blocked thread in this case, as reported by jconsole, will be something like java.lang.Thread.State: WAITING (on object monitor)

Assuming all methods are normal instance methods, then they will share the same monitor when invoked on the same object. That is, if you had something like:

// Thread 1
A a1 = new A();
a1.m1();

// Thread 2
A a2 = new A();
a2.m2()

then in this case, the second thread will be able to call the method, because it's trying to obtain the implicit monitor of the a2 object, which is not locked by thread 1. But if thread 2 tried to call a1.m2(), then it would block until thread 1 had finished executing m1().

If you have static methods, then they obtain the explicit monitor of the class itself (A.class in my hypothetical-naming case), so will not be blocked by any instance method invocations.

Muzhik answered 1/7, 2010 at 17:8 Comment(3)
Actually, it will be in the BLOCKED state, not the WAITING state.Subroutine
Calling a2.m2() in the above example is a bit misleading. Since a1 and a2 are different instances of class A, each has its own lock. Therefore, even a1.m1() and a2.m1() can be executed simultaneously.Caiman
@Caiman - that was the entire point I was making in that section, based on the bolded statement preceeding it. And since the question is asking about whether m1 and m2 can be called at once, that's what I stuck with in the example.Muzhik
P
4

No, it couldn't. That's the only point there is to synchronized: different threads can't do these things simultaneously (You don't have to guard against the same thread doing them simultaneously, because a single thread can't do anything in parallel at all.) The state of the waiting thread is 'waiting for lock'. (With a sufficiently modern JVM you can actually have this state displayed on the console if you ask in the right way.)

Prehistory answered 1/7, 2010 at 17:10 Comment(0)
C
1

If t1 access the m1 method (synchronized method), could t2 thread access m2 method (synchronized method) simultaneously?

No. Thread t2 will wait for Thread t1 to release the lock. In your same example, t2 can access method m4 which is not synchronized.

Locks In synchronized Methods

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

When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception

Coming back to your second query:

If not, what would be the state of t2 ?

Thread t2 is in blocked state and waiting for Thread t1 to release the lock.

From java documentation page:

making synchronized method have two effects.

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.

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all thread

Chilton answered 17/2, 2016 at 14:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.