I saw this in a tutorial, they asked if there is a problem with the following code. To me it looked like b() cannot be accessed as a() is already having the control over the monitor. Am I right in thinking so?
public class Test {
public synchronized void a() {
b();
System.out.println("I am at a");
}
public synchronized void b() {
System.out.println("I am at b");
}
}
No, there is no problem with that code. Note two things:
synchronized SomeType foo() { ... }
is equivalent to
SomeType foo() {
synchronized (this) { ... }
}
It locks the this
instance of the enclosing class. So, in your case a()
and b()
are locking the same thing
If a thread is already holding a lock on some object's monitor, it prevents another thread from acquiring a lock on the same object, but the same thread can acquire more locks if it needs too, that is not affected. So
public synchronized void a() { // acquires lock on this
b(); // also aquires lock on this, but it's ok because it is the same thread
System.out.println("I am at a");
}
While a thread is inside a()
, no other thread will be able to call either a()
or b()
on the same instance. If they try to, they will have to wait until the current thread exits a()
. But the current thread itself is not affected, it can call any synchronized method on this object, because it is already holding the lock.