同步方法中的线程锁定

sat*_*esh 2 java multithreading

我读到java中的每个对象都有一个锁.当用该对象调用synchronized方法时,线程将获取该内容.同时线程可以获取多个锁.

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();        
}
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,一个同步方法r()从run中调用,然后该特定线程获取该对象的锁定tt.now再次从r()r1()被调用.

我的问题是当进入r()时获取tt锁,然后它如何进入r1(),因为已经获取了该对象上的锁.

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();   

}
}
Run Code Online (Sandbox Code Playgroud)

为什么这个代码正在运行,因为我正在运行两个不同的对象...

Mik*_*els 5

Java的内部锁(与synchronized关键字一起使用)是可重入的.输入所需的锁定与进入所需的锁定r1相同r.已经拥有锁的线程可以重新获取它.你可以想到线程获得相同锁的次数有一个计数器.在方法中r1,调用线程已获得两次相同的锁.一旦"计数"回到零,锁只能用于其他线程; 也就是说,一旦获得锁的线程释放它的次数与获得锁的次数完全相同.

编辑:以下是五个线程的示例,每个线程在两个需要相同锁定的相互递归方法之间跳转.通过运行此示例,您可以看到methodOne在线程完全完成递归之前没有线程将进入,并且同一线程连续输入synchronized共享相同锁的相同(或不同)方法没有问题.

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

样本输出(抱歉长度):

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
Run Code Online (Sandbox Code Playgroud)

  • 而迈克描述但不使用的关键词是"可重入",意味着持有锁的任何人都能够在同一个锁上同步输入(或重新输入)代码. (2认同)