同步方法中的线程锁定

时间:2011-04-12 04:29:32

标签: 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();        
}
}

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

我的问题是当它进入r()时获取tt lock然后它如何进入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();   

}
}

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

2 个答案:

答案 0 :(得分:5)

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

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

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

答案 1 :(得分:4)

因为锁定可重入。锁的所有者(获取它的线程)可以重新获取它。

  

可重入互斥是互惠的   排除机制。在一个折返   互斥,同一个线程可以获得   多次锁定。但是,锁定   必须释放相同数量的   时间或其他线程将是   无法获得锁定

来源:wiki