可重入锁(Reentrant Lock)是一种支持线程重复获取同一把锁的锁机制。当一个线程获得了某个对象的锁,再次请求此对象锁时仍然会得到该锁。Java 中的 synchronized
关键字隐式地提供了可重入锁的机制,而 ReentrantLock
显式提供了这一特性。
以下是可重入锁的一些特点和使用场景:
-
重入性: 当一个线程持有一个锁的时候,还可以再次获取该锁而不发生死锁。这是通过记录锁的持有者和计数器的方式实现的。
-
公平锁和非公平锁:
ReentrantLock
提供了公平锁和非公平锁两种模式。在公平锁模式下,线程按照它们发出请求的顺序获取锁。在非公平锁模式下,线程可能会在请求的瞬间获取锁。ReentrantLock fairLock = new ReentrantLock(true); // 公平锁 ReentrantLock nonFairLock = new ReentrantLock(false); // 非公平锁
-
条件变量:
ReentrantLock
支持Condition
对象,通过newCondition()
方法创建,可以用于实现更灵活的线程通信。ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition();
-
锁的中断响应:
ReentrantLock
提供了对中断的响应,线程可以在等待锁的过程中被中断。ReentrantLock lock = new ReentrantLock(); try { lock.lockInterruptibly(); // 响应中断 // 代码块 } catch (InterruptedException e) { // 处理中断 } finally { lock.unlock(); }
-
可定时锁:
ReentrantLock
提供了tryLock(long timeout, TimeUnit unit)
方法,可以在指定的时间内尝试获取锁。ReentrantLock lock = new ReentrantLock(); if (lock.tryLock(10, TimeUnit.SECONDS)) { try { // 代码块 } finally { lock.unlock(); } } else { // 获取锁失败,做相应处理 }
-
可中断的获取锁:
ReentrantLock
提供了lockInterruptibly()
方法,可以在等待锁的过程中响应中断。ReentrantLock lock = new ReentrantLock(); try { lock.lockInterruptibly(); // 代码块 } catch (InterruptedException e) { // 处理中断 } finally { lock.unlock(); }
可重入锁通常用于需要更灵活的锁控制、实现公平锁、需要支持中断的场景,以及需要更细粒度的锁定的情况。在需要这些特性的情况下,使用 ReentrantLock
是一种较为灵活和强大的选择。