Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronized method calls itself recursively. Is this broken?

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?

like image 812
Thom Avatar asked Nov 02 '12 15:11

Thom


People also ask

Can we call synchronized method recursively?

So yes, that could cause a stackoverflow (harhar).

Is it safe to call a synchronized method from 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.

What happens when synchronized method is called?

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.

Does Break work in recursion?

Basically, with range and error checking in advance of the recursive method/function, you shouldn't need to break out. Depending on your algorithm, however, you may need to signal to the whole stack that you're good to go.


1 Answers

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

like image 98
Duncan Jones Avatar answered Sep 16 '22 11:09

Duncan Jones