可重入锁
可重入锁(Reentrant Lock)是一种支持锁重入的同步机制,它允许同一个线程多次获取同一把锁。在Java中,synchronized关键字和ReentrantLock类提供的锁都是可重入的。
可重入锁的特性:
-
线程拥有性:一旦线程获取了锁,它就拥有了这个锁,并且可以再次获取这个锁而不会被自己阻塞。这是通过跟踪已经拥有锁的线程和锁的持有计数来实现的。
-
锁计数:当线程首次获取锁时,持有计数设置为1。如果相同的线程再次获取这个锁,计数会递增。每次退出同步块时,计数会递减。当计数到达0时,锁被释放。
-
防止死锁:由于锁可以被同一个线程多次获取,因此可重入性可以防止在递归调用或者调用同一线程中的其他同步方法时发生死锁。
为什么需要可重入锁:
可重入锁解决了某些同步和递归调用的问题。如果没有可重入锁,当一个线程试图获取它已经持有的锁时,它会导致死锁。例如,如果有一个同步方法调用另一个同步方法,并且它们都需要相同的锁,那么在没有可重入锁的情况下,线程将会在尝试获取第二个方法的锁时阻塞自己。
Java中的可重入锁:
-
synchronized关键字:在Java中,synchronized关键字提供了一种内置的锁机制,它是可重入的。如果一个线程已经拥有对象的锁,当它再次请求时,请求会成功,并且锁的持有计数会递增。
-
ReentrantLock类:ReentrantLock是java.util.concurrent.locks包中的一个类,它也提供了可重入锁的功能。与synchronized不同,ReentrantLock提供了更高的灵活性,例如尝试非阻塞获取锁(tryLock),设置公平性策略,以及与Condition对象配合使用来实现等待/通知模式。
可重入锁是并发编程中一个非常重要的概念,因为它们提供了一种安全地在多线程环境中重复请求锁的方法,同时避免了潜在的死锁风险。