Java synchronisation uses a recursive lock for the instance of the synchronised method. It is as if each instance had a recursive lock, and @synchronized would lock that recursive lock (JVM uses a more clever method obviously). Therefore:
- Any number of threads can use @synchronized for different objects.
- One thread can use @synchronized for the same object multiple times.
- One thread can use @synchronized for any number of objects that are not @synchronized by any other thread.
For @synchronized class methods, a recursive lock for the class itself is used. Same rules apply as above, since classes are first class objects.
java allows only one such method to run at a time
Well, that's absolutely not true. First, 10 threads can call ten synchronized methods of ten different instances, and they can all run at the first time. Each synchronized method can in turn call other synchronized methods of other instances, and as long as they are not used with @synchronized methods, that will also work. And each @synchronized method can recursively call @synchronized methods of the same instance, as much as it likes.
The restriction is: No two threads can run @synchronized methods of the same instance simultaneously, or run @synchronized class methods of the same class simultaneously.