asp.net答辩做网站,网站外链推广平台,公司品牌策划设计,博物馆建设网站ReentrantLock 是 Java 中的一个高级同步机制#xff0c;它提供了比传统的 synchronized 方法和语句更灵活的锁定操作。ReentrantLock 实现了 Lock 接口#xff0c;并且完全依赖于 AbstractQueuedSynchronizer (AQS) 的扩展来实现其同步行为。
ReentrantLock 特性
可重入: …ReentrantLock 是 Java 中的一个高级同步机制它提供了比传统的 synchronized 方法和语句更灵活的锁定操作。ReentrantLock 实现了 Lock 接口并且完全依赖于 AbstractQueuedSynchronizer (AQS) 的扩展来实现其同步行为。
ReentrantLock 特性
可重入: 同一个线程可以多次获得同一把锁。公平性: 可以设置锁的公平性。公平锁意味着等待时间最长的线程会首先获得锁。锁绑定多个条件: 可以绑定多个 Condition 实例实现线程间更精细的同步。
ReentrantLock 实现原理
ReentrantLock 在内部通过其静态内部类 Sync 来使用 AQS。Sync 是一个抽象类它扩展了 AQS并提供了所有锁操作的基础。Sync 有两个子类 FairSync 和 NonfairSync分别提供公平和非公平锁的操作。公平和非公平锁的主要区别在于是否考虑线程等待的顺序。
以下是 ReentrantLock 中的一些关键方法的内部实现概念
lock()
非公平锁 (NonfairSync) 和公平锁 (FairSync) 的 lock() 方法略有不同。在非公平锁中调用 lock() 会直接尝试获取锁如果成功则立即返回如果失败则进入同步队列等待。对于公平锁当一个线程调用 lock()它会首先检查是否有其他线程正等待获取锁即使当前锁是可用的也会保证按照等待的先后顺序来获取锁。
public void lock() {sync.lock();
}unlock()
释放锁的操作是通过调用 AQS 的 tryRelease(int arg) 方法来实现的。tryRelease(int arg) 将会在成功释放锁时返回 true通知后继节点的线程尝试获取锁。
public void unlock() {sync.release(1);
}tryLock()
该方法尝试获取锁如果锁立即可用即不存在争用则成功获取并返回 true如果锁不可用则返回 false此方法不会等待。
public boolean tryLock() {return sync.nonfairTryAcquire(1);
}lockInterruptibly()
该方法与 lock() 相似但它允许在等待锁的过程中响应中断。如果当前线程在进入同步队列或者已经在队列中等待时被中断它会抛出 InterruptedException 并退出锁申请。
public void lockInterruptibly() throws InterruptedException {sync.acquireInterruptibly(1);
}newCondition()
ReentrantLock 提供了自己的 Condition 实现这允许与内部锁状态进行更紧密的协作。
public Condition newCondition() {return sync.newCondition();
}AQS 在 ReentrantLock 中的使用
ReentrantLock 在 AQS 的基础上定义了资源锁的获取和释放方式
获取锁: AQS 通过 tryAcquire(int arg) 方法的覆写来定义锁的获取行为。如果当前状态为0说明锁未被持有试图设置状态为1表示锁被当前线程独占。释放锁: AQS 通过 tryRelease(int arg) 方法的覆写来定义锁的释放行为。它尝试将状态设置回0以便其他线程可以获取锁。
这些重写的方法会利用 AQS 提供的原子性状态操作方法如 getState(), setState(int newState), compareAndSetState(int expect, int update) 等来管理同步状态。
ReentrantLock 的源码示例
下面是一个简化版的 ReentrantLock 实现突出显示了 AQS 在其中的应用
public class ReentrantLock implements Lock, java.io.Serializable {private final Sync sync;abstract static class Sync extends AbstractQueuedSynchronizer {abstract void lock();final boolean nonfairTryAcquire(int acquires) {final Thread current Thread.currentThread();int c getState();if (c 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);return true;}}else if (current getExclusiveOwnerThread()) {int nextc c acquires;if (nextc 0) // overflowthrow new Error(Maximum lock count exceeded);setState(nextc);return true;}return false;}protected final boolean tryRelease(int releases) {int c getState() - releases;if (Thread.currentThread() ! getExclusiveOwnerThread())throw new IllegalMonitorStateException();boolean free false;if (c 0) {free true;setExclusiveOwnerThread(null);}setState(c);return free;}// 省略其他方法...}static final class NonfairSync extends Sync {final void lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}// 省略其他方法...}static final class FairSync extends Sync {final void lock() {acquire(1);}// 省略其他方法...}// 构造函数 - 创建公平或非公平的锁public ReentrantLock(boolean fair) {sync fair ? new FairSync() : new NonfairSync();}// 实现Lock接口的方法public void lock() {sync.lock();}// 省略其他方法...
}在上述示例中ReentrantLock 包含两个 Sync 的内部类FairSync 和 NonfairSync。lock() 方法调用 acquire(1)它是 AQS 中的方法负责管理队列中线程的排队和阻塞行为。tryAcquire(int arg) 和 tryRelease(int arg) 方法在 Sync 类中被定义它们通过 AQS 提供的方法来操作同步状态。
通过这种方式ReentrantLock 利用 AQS 的基础设施来实现锁的功能并提供了丰富的同步操作。