understanding nested locks in java

i want to understand this:

String string;
public Test(String string){
     this.string = string;
     .....
}

public void foo(newObjectPerCall o) {
        synchronized (o) {
            //each thread can enter here because the object passed is always different
            ....
            synchronized (string) {
                // acquire this lock if the String is free.
            }
        }
    }

public synchronized void function() {

}

public static void main(){
    Test test = new Test("hello");
    for(int i = 0; i < 10;i++){
         WorkerThread workerThread = new WorkerThread(test);
         workerThread.start(); 
   }
 }

thread class

public class WorkerThread extends Thread {

    private Test test;

    public WorkerThread(Test test) {
        this.test = test;
    }

    @Override
    public void run() {
        while (true) {
            test.foo(new Object());
            try {
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            test.function();
        }
    }
}

my doubts are:

  • if one thread acquire the inner lock, other threads that acquired the outer lock, will remains inside the foo function?
  • When on thread ,for some reasons, remains outside the foo function, can this one acquire the lock of test instance inside function?
Jon Skeet
people
quotationmark

if one thread acquire the inner lock, other threads that acquired the outer lock, will remains inside the foo function?

Yes. They will block, waiting to acquire the monitor for string.

When on thread ,for some reasons, remains outside the foo function, can this one acquire the lock of test instance inside function?

Yes, it's entirely independent of the other monitors. A synchronized instance method is just equivalent to one whose body is

synchronized (this) {
    ...
}

If no other thread already owns the monitor for this, the "new" thread can acquire it regardless of what other monitors are owned. But as all your worker threads are using the same instance of Test, only one of them will be able to be "in" function() at a time. That can be at the same time as another thread is executing foo() though.

people

See more on this question at Stackoverflow