java多线程之7嵌套锁的概念

以上内容均来自于本书和我的自己理解的总结

Java Threads, 3rd Edition [Book] (oreilly.com)

Nested locks are also supported by the ReentrantLock class—the class that implements the Lock interface that we have been using so far. If a lock request is made by the thread that currently owns the lock, the ReentrantLock object just increments an internal count of the number of nested lock requests. Calls to the unlock() method decrement the count. The lock is not freed until the lock count reaches zero. This implementation allows these locks to behave exactly like the synchronized keyword. Note, however, that this is a specific property of the ReentrantLock class and not a general property of classes that implement the Lock interface.

ReentrantLock类也支持嵌套锁,该类实现了我们目前使用的Lock 接口。如果锁请求是由当前拥有锁的线程发出的,则ReentrantLock对象只会增加嵌套锁请求数的内部计数。对unlock()方法的调用会减少计数。在锁计数达到零之前,锁不会被释放。此实现允许这些锁的行为与synchronized关键字完全相同。但是请注意,这是ReentrantLock类的特定属性,而不是实现Lock 接口的类的继承自Lock的属性。 

This was a simple example. A more complex—and very common—example is that of cross-calling methods. It is possible for a method of one class to call methods of another class, which in turn may call methods of the original class. If Java did not support nested locks—and the methods of both classes were synchronized—we could deadlock the program.

 一个更复杂且非常常见的例子是交叉调用方法。一个类的方法可以调用另一个类的方法,而另一个类又可以调用原始类的方法。如果Java不支持嵌套锁,并且两个类的方法都是同步的,那么我们可能会使程序死锁。

The deadlock occurs because the final method tries to grab a lock that the current thread has already grabbed. This lock can't be freed until the original method unlocks it, but it can't unlock it until it completes the execution of the original method. And the original method can't complete its execution because the final method does not return: it is still waiting to grab the lock.

The deadlock occurs because the final method tries to grab a lock that the current thread has already grabbed. This lock can't be freed until the original method unlocks it, but it can't unlock it until it completes the execution of the original method. And the original method can't complete its execution because the final method does not return: it is still waiting to grab the lock.

The deadlock occurs because the final method tries to grab a lock that the current thread has already grabbed. This lock can't be freed until the original method unlocks it, but it can't unlock it until it completes the execution of the original method. And the original method can't complete its execution because the final method does not return: it is still waiting to grab the lock.

死锁发生是因为最后一个方法试图获取当前线程已经获取的锁。在原始方法解除锁定之前,无法释放此锁,但在完成原始方法的执行之前,无法解除锁定。原始方法无法完成其执行,因为最终方法没有返回:它仍在等待获取原始方法已经获得的锁

Cross-calling methods and callbacks are very prevalent in Java's core library—particularly the windowing system, with its dependency on event handlers and listeners. Developing threaded applications—or even just using Java's standard classes—would be very difficult if nested locks were not supported 

交叉调用方法和回调在Java的核心库中非常普遍,尤其是窗口系统,它依赖于事件处理程序和侦听器。如果不支持嵌套锁,开发线程化应用程序甚至仅仅使用Java的标准类都将非常困难 

Is it possible to detect how many times a lock has been recursively acquired? It is not possible to tell with the synchronized keyword, and the Lock interface does not provide a means to detect the number of nested acquisitions. However, that functionality is implemented by the ReentrantLock class:

 是否可以检测一个锁被递归获取了多少次?无法使用synchronized关键字进行判断,并且Lock接口不提供检测嵌套采集数量的方法。但是,该功能由ReentrantLock类实现:

public class ReentrantLock implements Lock {

    public int getHoldCount( );

    public boolean isLocked( );

    public boolean isHeldByCurrentThread( );

    public int getQueueLength( );

}

The getHoldCount() method returns the number of acquisitions that the current thread has made on the lock. A return value of zero means that the current thread does not own the lock: it does not mean that the lock is free. To determine if the lock is free—not acquired by any thread—the isLocked() method may be used. 

getHoldCount()方法返回当前线程对锁进行的获取次数。返回值为零意味着当前线程不拥有锁:这并不意味着锁是自由的。要确定锁是否空闲,而不由任何线程获取,可以使用isLocked()方法 

Two other methods of the ReentrantLock class are also important to this discussion. The isHeldByCurrentThread() method is used to determine if the thread is owned by the current thread, and the getQueueLength() method can be used to get an estimate of the number of threads waiting to acquire the lock. This value that is returned is only an estimate due to the race condition that exists between the time that the value is calculated and the time that the value is used after it has been returned 

ReentrantLock类的另外两个方法对本次讨论也很重要。isHeldByCurrentThread()方法用于确定线程是否属于当前线程,getQueueLength()方法可用于估计等待获取锁的线程数。返回的这个值只是由于计算该值的时间和返回后使用该值的时间之间存在的竞争条件而产生的估计值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值