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

JavaThread Safety

Java Problem Overview


If a synchronized method calls another synchronized method, is it thread safe?

void synchronized method1() {
     method2()
}

void synchronized method2() {
}

Java Solutions


Solution 1 - Java

Yes, when you mark methods as synchronized, then you are really doing this:

void method1() {
    synchronized (this) {
        method2()
    }
}

void method2() {
    synchronized (this) {
    }
}

When the thread call gets into method2 from method1, then it will ensure that it holds the lock to this, which it will already, and then it can pass through.

When the thread gets directly into method1 or method2, then it will block until it can get the lock (this), and then it will enter.

As noted by James Black in the comments, you do have to be aware with what you do inside of the method body.

private final List<T> data = new ArrayList<T>();

public synchronized void method1() {
    for (T item : data) {
        // ..
    }
}

public void method3() {
    data.clear();
}

Suddenly it's not thread safe because you are looking at a ConcurrentModificationException in your future because method3 is unsynchronized, and thus could be called by Thread A while Thread B is working in method1.

Solution 2 - Java

> Is a method marked with synchronized call another synchronized method thread safe.

In general, it is not possible to say. It depends on what the methods do, and what other methods on the same and other classes do.

However, we can be sure that calls to method1 and method2 on the same object made by different threads will not execute simultaneously. Depending on what the methods do, this may be sufficient to say that the class is thread-safe with respect to these methods.

Solution 3 - Java

From the Java Tutorials site http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

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

  2. 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 threads

So Java will ensure that if 2 threads are executing the same method, the methods will not executed consurrently but one after another.

But you need to be aware of the Liveness problem, http://download.oracle.com/javase/tutorial/essential/concurrency/starvelive.html

And also whether you are locking uncessarily, cause in the code you used this, which locks the whole object, if your object only needs sync access to one variable you should just lock that variable.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser705414View Question on Stackoverflow
Solution 1 - JavapickypgView Answer on Stackoverflow
Solution 2 - JavaStephen CView Answer on Stackoverflow
Solution 3 - JavaStephen LeeView Answer on Stackoverflow