ReentrantLock - 在被调用的方法中解锁

时间:2015-05-15 07:09:21

标签: java multithreading locking

ReentrantLock

void a() {

    lock.lock();    //got intrinsic lock 
    System.out.println(Thread.currentThread().getName());
    System.out.println("In A");
    b();            // called method in synchronized block

    Thread.sleep(2000);    // sleeping current thread(avoided try catch for simplicity) 


    System.out.println("after calling method B()");
    System.out.println(Thread.currentThread().getName());

    lock.unlock();    // releasing intrinsic lock

}

void b() {

    lock.lock();// getting intrinsic lock, no problem as calling thread already has intrinsic lock 
    System.out.println(Thread.currentThread().getName());
    System.out.println("In B");
    lock.unlock();    // intentionally releasing lock, so now there is no lock .

        Thread.sleep(2000);
}

产生两个线程Thread-0和Thread-1都调用a()。

在()中,我得到内在锁定,而不是我调用b()。在b()中我也获得内在锁定,因此我将获得当前线程拥有的相同锁定。 现在我故意在b()中解锁,释放锁定,以便其他等待线程可以获得锁定,只是为了确保我甚至让当前线程休眠。当我的线程在b()中休眠2000毫秒而在一个()中休眠2000毫秒时,我期待其他线程通过获取释放的锁来运行a()。

但它根据我的输出没有发生

输出: -

Thread-0
In A
Thread-0
In B
after calling method B()
Thread-0
Thread-1
In A
Thread-1
In B
after calling method B()
Thread-1

2 个答案:

答案 0 :(得分:3)

  

现在我故意在b()中解锁,释放锁定,以便其他等待的线程可以获得锁定

不,它没有完全释放它 - 它只是递减锁定计数。在致电unlock之前,您已拨打lock 两次,因此保留计数为2.拨打unlock后,保留计数为1,因此它仍然阻止其他线程获取锁定。基本上,您的代码有点像:

void a() {
    synchronized (foo) {
        b();
    }
}

void b() {
    synchronized(foo) {
        // In here, the count is 2
    }
    // Now the count is still 1...
}

答案 1 :(得分:2)

了解锁类的名称是可重入锁定非常重要,这意味着同一个线程可以多次获取锁定,但必须释放相同的次数才能走出监视器。

在Java-8中引入了一个名为StampedLock的其他锁类,它不是可重入的,并且会有不同的行为。