Synchronized method calls itself recursively. Is this broken?
Solution 1
In Java, synchronized locks are reentrant.
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.
Source: see bottom of this page
Solution 2
A synchronized method needs to be able to get a lock on the monitor object. The monitor object is the instance (or class for a static method). A thread that already has the lock does not need to get it again. So yes, that could cause a stackoverflow (harhar).
Solution 3
from the java tutorials:
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.
So I think the syncronized keyword worked as expected, and a synchronized recursive call is perfectly legal (and working) in java.
Thom
Seasoned software architect building mobile word games for himself. Background in web services and Spring Framework.
Updated on June 05, 2022Comments
-
Thom almost 2 years
The point of this question is to illustrate that Java is not working as I expected.
How would you expect the following code to behave?
public class SynchTester { private static SynchTester synchTester; public synchronized static SynchTester getSynchTester(){ if(synchTester==null){ synchTester = new SynchTester(); } return synchTester; } private SynchTester() { SynchTester myTester = getSynchTester(); } public static void main(String[] args) { SynchTester tester = SynchTester.getSynchTester(); } }
I would expect it to hang with a deadlock waiting on the recursion to complete, but instead it throws StackOverflow. Evidently synchronized does not block access to the same thread.
Is this a bug?
-
Thom over 11 yearsThat's kinda what I was thinking. Cite your source, please?
-
akaIDIOT over 11 years@Thom Personal experience, mostly, but also docs.oracle.com/javase/tutorial/essential/concurrency/…
-
Jack almost 4 yearsThe later scenario discussed here softwareengineering.stackexchange.com/questions/286374/…