简体   繁体   中英

Thread locking in synchronized method

I read that every object in java have a lock.That will be acquired by the thread when a synchronized method is called with that object.And at the same time thread can acquire more than one lock.

public class ThreadTes extends Thread{

public static void main(String[] args){

    ThreadTes t=new ThreadTes();
    t.start();

}
synchronized public void r(){
    System.out.println("in r method");
    this.r1();
}
synchronized public void r1(){
    System.out.println("in r1 method");
}
public void run(){
    ThreadTes tt=new ThreadTes();
    tt.r();        
}
}

In the above code one synchronized method r() is called from run and then that particular thread acquire lock of that object tt.now again from r() r1() is called.

My question is as tt lock is acquired as it enters into r() then how come it enters into r1() as the lock on that object is already acquired.

public class ThreadTes extends Thread{

public static void main(String[] args){

    ThreadTes t=new ThreadTes();
    t.start();

}
synchronized public void r(){
    System.out.println("in r method");
    ThreadTes ttt=new ThreadTes();
    ttt.r1();
}
synchronized public void r1(){
    System.out.println("in r1 method");
}
public void run(){
    ThreadTes tt=new ThreadTes();
    tt.r();   

}
}

how come this code is running as i am running with two different objects...

Java's intrinsic locks (used with the synchronized keyword) are re-entrant. The lock required to enter r1 is the same lock as the one required to enter r . A thread which already owns a lock is allowed to re-acquire it. You can think of there being a counter for the number of times a thread has acquired the same lock. In method r1 , the calling thread has acquired the same lock twice. The lock is only available to other threads once the "count" goes back to zero; that is, once the thread that obtained the lock has released it exactly as many times as it obtained it.

Edit : Here is an example of five threads that each bounce between two mutually-recursive methods that both require the same lock. By running this example you can see that no thread will enter methodOne until the thread before it has completely finished recursing, and that there is no problem for the same thread to continually enter the same (or different) synchronized methods that share the same lock.

public class LockExample {
    private static synchronized void methodOne(int depth) {
        if (depth == 0) {
            return;
        } else {
            System.out.println(Thread.currentThread().getName() + " methodOne (in), depth " + depth);
            methodTwo(depth - 1);
            System.out.println(Thread.currentThread().getName() + " methodOne (out), depth " + depth);
        }
    }

    private static synchronized void methodTwo(int depth) {
        if (depth == 0) {
            return;
        } else {
            System.out.println(Thread.currentThread().getName() + " methodTwo (in), depth " + depth);
            methodOne(depth - 1);
            System.out.println(Thread.currentThread().getName() + " methodTwo (out), depth " + depth);
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    methodOne(10);
                }
            });
            t.setName("Thread" + i);
            t.start();
        }
    }
}

Sample output (sorry for length):

Thread0 methodOne (in), depth 10
Thread0 methodTwo (in), depth 9
Thread0 methodOne (in), depth 8
Thread0 methodTwo (in), depth 7
Thread0 methodOne (in), depth 6
Thread0 methodTwo (in), depth 5
Thread0 methodOne (in), depth 4
Thread0 methodTwo (in), depth 3
Thread0 methodOne (in), depth 2
Thread0 methodTwo (in), depth 1
Thread0 methodTwo (out), depth 1
Thread0 methodOne (out), depth 2
Thread0 methodTwo (out), depth 3
Thread0 methodOne (out), depth 4
Thread0 methodTwo (out), depth 5
Thread0 methodOne (out), depth 6
Thread0 methodTwo (out), depth 7
Thread0 methodOne (out), depth 8
Thread0 methodTwo (out), depth 9
Thread0 methodOne (out), depth 10
Thread2 methodOne (in), depth 10
Thread2 methodTwo (in), depth 9
Thread2 methodOne (in), depth 8
Thread2 methodTwo (in), depth 7
Thread2 methodOne (in), depth 6
Thread2 methodTwo (in), depth 5
Thread2 methodOne (in), depth 4
Thread2 methodTwo (in), depth 3
Thread2 methodOne (in), depth 2
Thread2 methodTwo (in), depth 1
Thread2 methodTwo (out), depth 1
Thread2 methodOne (out), depth 2
Thread2 methodTwo (out), depth 3
Thread2 methodOne (out), depth 4
Thread2 methodTwo (out), depth 5
Thread2 methodOne (out), depth 6
Thread2 methodTwo (out), depth 7
Thread2 methodOne (out), depth 8
Thread2 methodTwo (out), depth 9
Thread2 methodOne (out), depth 10
Thread3 methodOne (in), depth 10
Thread3 methodTwo (in), depth 9
Thread3 methodOne (in), depth 8
Thread3 methodTwo (in), depth 7
Thread3 methodOne (in), depth 6
Thread3 methodTwo (in), depth 5
Thread3 methodOne (in), depth 4
Thread3 methodTwo (in), depth 3
Thread3 methodOne (in), depth 2
Thread3 methodTwo (in), depth 1
Thread3 methodTwo (out), depth 1
Thread3 methodOne (out), depth 2
Thread3 methodTwo (out), depth 3
Thread3 methodOne (out), depth 4
Thread3 methodTwo (out), depth 5
Thread3 methodOne (out), depth 6
Thread3 methodTwo (out), depth 7
Thread3 methodOne (out), depth 8
Thread3 methodTwo (out), depth 9
Thread3 methodOne (out), depth 10
Thread1 methodOne (in), depth 10
Thread1 methodTwo (in), depth 9
Thread1 methodOne (in), depth 8
Thread1 methodTwo (in), depth 7
Thread1 methodOne (in), depth 6
Thread1 methodTwo (in), depth 5
Thread1 methodOne (in), depth 4
Thread1 methodTwo (in), depth 3
Thread1 methodOne (in), depth 2
Thread1 methodTwo (in), depth 1
Thread1 methodTwo (out), depth 1
Thread1 methodOne (out), depth 2
Thread1 methodTwo (out), depth 3
Thread1 methodOne (out), depth 4
Thread1 methodTwo (out), depth 5
Thread1 methodOne (out), depth 6
Thread1 methodTwo (out), depth 7
Thread1 methodOne (out), depth 8
Thread1 methodTwo (out), depth 9
Thread1 methodOne (out), depth 10
Thread4 methodOne (in), depth 10
Thread4 methodTwo (in), depth 9
Thread4 methodOne (in), depth 8
Thread4 methodTwo (in), depth 7
Thread4 methodOne (in), depth 6
Thread4 methodTwo (in), depth 5
Thread4 methodOne (in), depth 4
Thread4 methodTwo (in), depth 3
Thread4 methodOne (in), depth 2
Thread4 methodTwo (in), depth 1
Thread4 methodTwo (out), depth 1
Thread4 methodOne (out), depth 2
Thread4 methodTwo (out), depth 3
Thread4 methodOne (out), depth 4
Thread4 methodTwo (out), depth 5
Thread4 methodOne (out), depth 6
Thread4 methodTwo (out), depth 7
Thread4 methodOne (out), depth 8
Thread4 methodTwo (out), depth 9
Thread4 methodOne (out), depth 10

Because the lock is reentrant . Owner of the lock(A thread that acquire it) can reacquire it.

A reentrant mutex is a mutual exclusion mechanism. In a reentrant mutex, the same thread can acquire the lock multiple times. However, the lock must be released the same number of times or else other threads will be unable to acquire the lock

Source: wiki

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM