Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do two synchronized methods execute simultaneously

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?

like image 739
Isabel Jinson Avatar asked Jul 01 '10 17:07

Isabel Jinson


3 Answers

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
like image 106
aioobe Avatar answered Oct 17 '22 22:10

aioobe


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.

like image 25
Andrzej Doyle Avatar answered Oct 17 '22 23:10

Andrzej Doyle


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.)

like image 4
Kilian Foth Avatar answered Oct 17 '22 22:10

Kilian Foth