A single thread is allowed to lock the same object multiple times. For each object, the Java virtual machine maintains a count of the number of times the object has been locked. An unlocked object has a count of zero. When a thread acquires the lock for the first time, the count is again incremented to one. Each time the thread acquires a lock on the same object, the count is again incremented. (Only the thread that already owns an object's lock is allowed to lock it again. As mentioned previously, no other thread can lock the object until the owning thread releases the lock.) Each time the thread releases the lock, the count is decremented. When the count reaches zero, the lock is released and made available to other threads.
synchronized(myLockObjA){
synchronized(myLockObjB){
synchronized(myLockObjA){
//Do something.
// lock count for myLockObjA = 2 and for myLockObjB = 1
while(!someCondition)
myLockObjA.wait(); //lock count for myLockObjA = 0 and for myLockObjB = 1
//Now the thread will have to acquire lock on myLockObjA again after getting a wake up call by notify/notifyAll method.
}
}
}
More information can be found here