| public class ReentrantLockDemo { |
| |
| public static void main(String[] args) { |
| ReentrantLock reentrantLock = new ReentrantLock(); |
| reentrantLock.lock(); |
| reentrantLock.unlock(); |
| } |
| |
| } |
| public ReentrantLock() { |
| sync = new NonfairSync(); |
| } |
-
查看sync

-
查看有参构造
| public ReentrantLock(boolean fair) { |
| sync = fair ? new FairSync() : new NonfairSync(); |
| } |

-
ReentrantLock实现了Lock接口

-
查看方法


-
查看内部类

-
查看lock方法
| public class ReentrantLockDemo { |
| |
| public static void main(String[] args) { |
| ReentrantLock reentrantLock = new ReentrantLock(); |
| reentrantLock.lock(); |
| reentrantLock.unlock(); |
| } |
| |
| } |
| public void lock() { |
| sync.acquire(1); |
| } |
| |
| public final void acquire(int arg) { |
| |
| if (!tryAcquire(arg) && |
| acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) |
| selfInterrupt(); |
| } |
| protected boolean tryAcquire(int arg) { |
| throw new UnsupportedOperationException(); |
| } |
- 查看非公平实现

| static final class NonfairSync extends Sync { |
| private static final long serialVersionUID = 7316153563782823691L; |
| protected final boolean tryAcquire(int acquires) { |
| return nonfairTryAcquire(acquires); |
| } |
| } |
| |
| # ctrl继续查看 |
| @ReservedStackAccess |
| 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) |
| throw new Error("Maximum lock count exceeded"); |
| setState(nextc); |
| return true; |
| } |
| return false; |
| } |
| public final void acquire(int arg) { |
| if (!tryAcquire(arg) && |
| acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) |
| selfInterrupt(); |
| } |
-
查看EXCLUSIVE

-
查看addWaiter方法
| private Node addWaiter(Node mode) { |
| Node node = new Node(mode); |
| |
| for (;;) { |
| Node oldTail = tail; |
| if (oldTail != null) { |
| node.setPrevRelaxed(oldTail); |
| if (compareAndSetTail(oldTail, node)) { |
| oldTail.next = node; |
| return node; |
| } |
| } else { |
| initializeSyncQueue(); |
| } |
| } |
| } |
| Node(Node nextWaiter) { |
| this.nextWaiter = nextWaiter; |
| THREAD.set(this, Thread.currentThread()); |
| } |
| private Node addWaiter(Node mode) { |
| Node node = new Node(mode); |
| |
| for (;;) { |
| Node oldTail = tail; |
| if (oldTail != null) { |
| node.setPrevRelaxed(oldTail); |
| if (compareAndSetTail(oldTail, node)) { |
| oldTail.next = node; |
| return node; |
| } |
| } else { |
| initializeSyncQueue(); |
| } |
| } |
| } |
| public final void acquire(int arg) { |
| if (!tryAcquire(arg) && |
| acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) |
| selfInterrupt(); |
| } |
| |
| |
| final boolean acquireQueued(final Node node, int arg) { |
| boolean interrupted = false; |
| try { |
| for (;;) { |
| final Node p = node.predecessor(); |
| if (p == head && tryAcquire(arg)) { |
| setHead(node); |
| p.next = null; |
| return interrupted; |
| } |
| if (shouldParkAfterFailedAcquire(p, node)) |
| interrupted |= parkAndCheckInterrupt(); |
| } |
| } catch (Throwable t) { |
| cancelAcquire(node); |
| if (interrupted) |
| selfInterrupt(); |
| throw t; |
| } |
| } |
| final Node predecessor() { |
| Node p = prev; |
| if (p == null) |
| throw new NullPointerException(); |
| else |
| return p; |
| } |
- 查看shouldParkAfterFailedAcquire方法
| private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { |
| int ws = pred.waitStatus; |
| if (ws == Node.SIGNAL) |
| |
| |
| |
| |
| return true; |
| if (ws > 0) { |
| |
| |
| |
| |
| do { |
| node.prev = pred = pred.prev; |
| } while (pred.waitStatus > 0); |
| pred.next = node; |
| } else { |
| |
| |
| |
| |
| |
| pred.compareAndSetWaitStatus(ws, Node.SIGNAL); |
| } |
| return false; |
| } |
| Status field, taking on only the values: |
| SIGNAL: The successor of this node is (or will soon be) blocked (via park), so the current node must unpark its successor when it releases or cancels. To avoid races, acquire methods must first indicate they need a signal, then retry the atomic acquire, and then, on failure, block. |
| CANCELLED: This node is cancelled due to timeout or interrupt. Nodes never leave this state. In particular, a thread with cancelled node never again blocks. |
| CONDITION: This node is currently on a condition queue. It will not be used as a sync queue node until transferred, at which time the status will be set to 0. (Use of this value here has nothing to do with the other uses of the field, but simplifies mechanics.) PROPAGATE: A releaseShared should be propagated to other nodes. This is set (for head node only) in doReleaseShared to ensure propagation continues, even if other operations have since intervened. 0: None of the above The values are arranged numerically to simplify use. Non-negative values mean that a node doesn |
| |
| # ctrl + shift + y 翻译后,如下几种状态 |
| 状态字段,仅取值: |
| SIGNAL:此节点的后继节点已(或即将)被阻塞(通过停放),因此当前节点在释放或取消时必须取消停放其后继节点。为了避免竞争,获取方法必须首先表明它们需要一个信号,然后重试原子获取,然后在失败时阻塞。 |
| CANCELLED:该节点由于超时或中断而被取消。节点永远不会离开这个状态。特别是,具有取消节点的线程永远不会再次阻塞。 |
| CONDITION:此节点当前位于条件队列中。在传输之前不会用作同步队列节点,此时状态将设置为 0。(此处使用此值与该字段的其他用途无关,但简化了机制。)传播:A releaseShared 应该传播到其他节点。这是在 doReleaseShared 中设置的(仅针对头节点),以确保传播继续进行,即使其他操作已经介入。 0:以上都不是 这些值以数字排列以简化使用。非负值意味着节点不需要发出信号。因此,大多数代码不需要检查特定值,只需检查符号即可。对于正常同步节点,该字段初始化为 0,对于条件节点,该字段初始化为 CONDITION。它使用 CAS 进行修改(或者在可能的情况下,无条件的 volatile 写入)。 |
| |
| volatile int waitStatus; |
| public class ReentrantLockDemo { |
| |
| public static void main(String[] args) { |
| ReentrantLock reentrantLock = new ReentrantLock(); |
| reentrantLock.lock(); |
| reentrantLock.unlock(); |
| } |
| |
| } |
| |
| # ctrl |
| public void unlock() { |
| sync.release(1); |
| } |
| public final boolean release(int arg) { |
| if (tryRelease(arg)) { |
| Node h = head; |
| if (h != null && h.waitStatus != 0) |
| unparkSuccessor(h); |
| return true; |
| } |
| return false; |
| } |
| protected boolean tryRelease(int arg) { |
| throw new UnsupportedOperationException(); |
| } |
- 查看实现类

| @ReservedStackAccess |
| 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; |
| } |
| public final boolean release(int arg) { |
| if (tryRelease(arg)) { |
| Node h = head; |
| if (h != null && h.waitStatus != 0) |
| unparkSuccessor(h); |
| return true; |
| } |
| return false; |
| } |
| |
| # ctrl |
| private void unparkSuccessor(Node node) { |
| |
| |
| |
| |
| |
| int ws = node.waitStatus; |
| if (ws < 0) |
| node.compareAndSetWaitStatus(ws, 0); |
| |
| |
| |
| |
| |
| |
| |
| Node s = node.next; |
| if (s == null || s.waitStatus > 0) { |
| s = null; |
| for (Node p = tail; p != node && p != null; p = p.prev) |
| if (p.waitStatus <= 0) |
| s = p; |
| } |
| if (s != null) |
| LockSupport.unpark(s.thread); |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决