本文共 3364 字,大约阅读时间需要 11 分钟。
ReentrantLock是Java Concurrent包中提供的一种可重入锁,主要用于实现多线程环境下的资源同步。可重入锁的意义在于允许持有锁的一线程多次获取锁资源,而无需每次都释放锁,这避免了死锁的发生,极大提升了多线程应用的性能和可靠性。
ReentrantLock的实现基础是AQS,一个抽象的同步队列器,用于实现两种同步模式:排他(独占)模式和共享模式。排他模式下,AQS提供了可重入锁的实现机制,而共享模式适用于线程之间可以并发访问的场景。
AQS的核心结构包括一个状态变量state、持有锁的线程Thread exclusiveOwnerThread,以及一个双端队列用于管理等待锁的线程。
AQS使用双端队列实现等待队列,头尾节点通过Node对象表示。每个节点包含:
waitStatus:等待状态,初始值为0。可能状态包括:
Thread thread:对应等待的线程。
节点的插入和移除通过自旋锁实现,以确保在高并发情况下操作的原子性。
ReentrantLock本身通过内部类Sync(继承自AQS)实现,可分为公平锁和非公平锁两种类型。
非公平锁的lock()
方法:
public final void lock() { if (compareAndSetState(0, 1)) { setExclusiveOwnerThread(Thread.currentThread()); } else { acquire(1); }}public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt();}
compareAndSet
获取锁,成功则更新exclusiveOwnerThread
;失败则加入等待队列。public final void lock() { acquire(1);}public final boolean tryAcquire(int acquires) { if (getQueue().hasQueuedPredecessors()) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(Thread.currentThread()); return true; } } return false;}
public void unlock() { sync.release(1);}public boolean release(int arg) { if (tryRelease(arg)) { unparkSuccessor(head); return true; } return false;}protected final boolean tryRelease(int releases) { if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); int c = getState() - releases; if (c == 0) { setExclusiveOwnerThread(null); setState(c); return true; } setState(c); return true;}
public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1);}public final void acquireInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) throw new InterruptedException(); if (!tryAcquire(arg)) doAcquireInterruptibly(arg);}private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); boolean failed = true; try { for (;;) { if (node.predecessor() == head && tryAcquire(arg)) { setHead(node); failed = false; return; } if (shouldParkAfterFailedAcquire(node.predecessor(), node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); }}
ReentrantLock通过AQS实现了高效的可重入锁机制,在多线程环境中提供了强大的同步能力。其设计巧妙地平衡了并发性能和正确性,适用于广泛的多线程场景。理解AQS内部工作原理是掌握ReentrantLock关键的前提,以便优化应用性能并避免潜在的死锁问题。
AQS的核心在于通过等待队列管理线程同步,支持多种同步模式的实现。非公平锁通过自旋锁实现快速入队,适合并发率高但并发竞争宽松的场景;而公平锁则确保等待线程按FIFO顺序获取锁,适合更严格的公平要求。ReentrantLock的设计为多线程开发提供了可靠的基础,值得深入研究和应用。
转载地址:http://czhzk.baihongyu.com/