【并发编程】AQS ReentrantLock 底层实现原理
创始人
2024-03-16 10:04:42
0

一、概述

synchronized上锁机制是通过对象头来实现的,通过锁升级的过程来完成加锁。(https://blog.csdn.net/zhangting19921121/article/details/106002751)

但是synchronized锁升级的过程犹如一个黑盒,我们无法掌控。因此,在实际的工作中ReentrantLock使用相对比较频繁。ReentrantLock显式地获取锁,释放锁,可中断,同时还支持实现公平锁等。常用的写法如下:

ReentrantLock lock = new ReentrantLock(false);//false为非公平锁, true为公平锁
lock.lock() //加锁
// todo 业务代码
lock.unlock() //解锁

假如说有t0,t1,t2三个线程来进行调用,t0获取锁,开始执行业务代码。此时,t1,t2都应该停在lock.lock()方法中,不能向下执行业务代码。那么怎么停在里面呢?可以借鉴synchronized自旋的实现,

while(true) {if (加锁成功) {break; // 跳出循环}
}

但是,一直让线程进行while循环,其实也是在不断消耗CPU。所以,如何让这些线程让出CPU呢?

while(true) {if (加锁成功) {break; // 跳出循环}Thread.yeild(); // 让出CPU的使用权
}

会有这样一个问题,假如说业务代码执行很慢,需要10几秒。此时只有t1,t2两个线程在等待获取锁还好,如果有100多个线程都在等待呢,那这100多个线程只能互相让来让去。如果改为Thread.sleep(睡眠时间);呢,但是这个睡眠时间选多少合适呢,这个时间不好确认,也不是一个很好的方法。那如果我把线程阻塞了,不让它再循环了,等待调度唤醒,减少线程间互相的让来来去或者是找一个合适的睡眠时间。

while(true) {if (加锁成功) {break; // 跳出循环}LockSupport.part();//阻塞线程,跳出循环
}

那谁去唤醒这些被阻塞的线程呢?

while(true) {if (加锁成功) {break; // 跳出循环}LockSupport.part();//阻塞线程,跳出循环
}
LockSupport.unpart(t);// 唤醒线程t

LockSupport.unpart(t)可以唤醒线程,但是我怎么知道唤醒哪个线程呢?可以使用一个对象来进行保存。

// lock.lock()
while(true) {if (加锁成功) {break; // 跳出循环}HashSet.add(t); // LinkedQueue也可以LockSupport.part();//阻塞线程,跳出循环
}
// todo 业务逻辑
// lock.unlock()
Thread t = HashSet.get();// LinkedQueue.take()
LockSupport.unpart(t);// 唤醒线程t

以上,便是加锁,解锁的简单实现。但是除了自旋,LockSupport,Queue外还需要什么呢?在if判断的地方,必须要保证只有一个线程能够进入,通过synchronized就可以实现这个功能。此外,java中还有CAS可以实现和synchronized一样的功能,ReentrantLock是一种基于AQS框架的应用实现的。

好啦,接下来就引入了本文的重点啦,继续往下看吧~

二、AQS

AQS(全称AbstractQueuedSynchronized),AQS定义了一套多线程访问共享资源 的同步器框架,是一个依赖状态(state)的同步器。

1.AQS基本特性

1-1.阻塞等待队列
1-2.共享/独占
1-3.公平/非公平
1-4.可重入
1-5.允许中断

2.AQS实现逻辑

2-1.AQS内部维护属性volatile int state (32位):state表示资源的可用状态,为0的时候表示当前锁并未被任何线程所持有。state三种访问方式:getState()、setState()、compareAndSetState()
2-2.AQS定义两种资源共享方式:Exclusive-独占(只有一个线程能执行,如ReentrantLock)、Share-共享(多个线程可以同时执行,如Semaphore/CountDownLatch)
2-3.AQS定义两种队列:同步等待队列、条件等待队列
不同的自定义同步器争用共享资源的方式也不同。自定义同步器在实现时只需要实现共享资源state的获取与释放方式即可,至于具体线程等待队列的维护(如获取资源失败入队/ 唤醒出队等),AQS已经在顶层实现好了。自定义同步器实现时主要实现以下几种方法:
isHeldExclusively():该线程是否正在独占资源。只有用到condition才需要去实现它。
tryAcquire(int):独占方式。尝试获取资源,成功则返回true,失败则返回false。
tryRelease(int):独占方式。尝试释放资源,成功则返回true,失败则返回false。
tryAcquireShared(int):共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。
tryReleaseShared(int):共享方式。尝试释放资源,如果释放后允许唤醒后续等待结点返回true,否则返回false。
在这里插入图片描述

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package java.util.concurrent.locks;import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import sun.misc.Unsafe;public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements Serializable {private static final long serialVersionUID = 7373984972572414691L;// 基于Node(prev、next)来构建的双向链表CLH private transient volatile AbstractQueuedSynchronizer.Node head;private transient volatile AbstractQueuedSynchronizer.Node tail;// 状态器,为0的时候表示当前锁并未被任何线程所持有private volatile int state;static final long spinForTimeoutThreshold = 1000L;private static final Unsafe unsafe = Unsafe.getUnsafe();private static final long stateOffset;private static final long headOffset;private static final long tailOffset;private static final long waitStatusOffset;private static final long nextOffset;protected AbstractQueuedSynchronizer() {}protected final int getState() {return this.state;}protected final void setState(int var1) {this.state = var1;}protected final boolean compareAndSetState(int var1, int var2) {return unsafe.compareAndSwapInt(this, stateOffset, var1, var2);}private AbstractQueuedSynchronizer.Node enq(AbstractQueuedSynchronizer.Node var1) {while(true) {AbstractQueuedSynchronizer.Node var2 = this.tail;if (var2 == null) {if (this.compareAndSetHead(new AbstractQueuedSynchronizer.Node())) {this.tail = this.head;}} else {var1.prev = var2;if (this.compareAndSetTail(var2, var1)) {var2.next = var1;return var2;}}}}private AbstractQueuedSynchronizer.Node addWaiter(AbstractQueuedSynchronizer.Node var1) {AbstractQueuedSynchronizer.Node var2 = new AbstractQueuedSynchronizer.Node(Thread.currentThread(), var1);AbstractQueuedSynchronizer.Node var3 = this.tail;if (var3 != null) {var2.prev = var3;if (this.compareAndSetTail(var3, var2)) {var3.next = var2;return var2;}}this.enq(var2);return var2;}private void setHead(AbstractQueuedSynchronizer.Node var1) {this.head = var1;var1.thread = null;var1.prev = null;}private void unparkSuccessor(AbstractQueuedSynchronizer.Node var1) {int var2 = var1.waitStatus;if (var2 < 0) {compareAndSetWaitStatus(var1, var2, 0);}AbstractQueuedSynchronizer.Node var3 = var1.next;if (var3 == null || var3.waitStatus > 0) {var3 = null;for(AbstractQueuedSynchronizer.Node var4 = this.tail; var4 != null && var4 != var1; var4 = var4.prev) {if (var4.waitStatus <= 0) {var3 = var4;}}}if (var3 != null) {LockSupport.unpark(var3.thread);}}private void doReleaseShared() {while(true) {AbstractQueuedSynchronizer.Node var1 = this.head;if (var1 != null && var1 != this.tail) {int var2 = var1.waitStatus;if (var2 == -1) {if (!compareAndSetWaitStatus(var1, -1, 0)) {continue;}this.unparkSuccessor(var1);} else if (var2 == 0 && !compareAndSetWaitStatus(var1, 0, -3)) {continue;}}if (var1 == this.head) {return;}}}private void setHeadAndPropagate(AbstractQueuedSynchronizer.Node var1, int var2) {AbstractQueuedSynchronizer.Node var3 = this.head;this.setHead(var1);if (var2 > 0 || var3 == null || var3.waitStatus < 0 || (var3 = this.head) == null || var3.waitStatus < 0) {AbstractQueuedSynchronizer.Node var4 = var1.next;if (var4 == null || var4.isShared()) {this.doReleaseShared();}}}private void cancelAcquire(AbstractQueuedSynchronizer.Node var1) {if (var1 != null) {var1.thread = null;AbstractQueuedSynchronizer.Node var2;for(var2 = var1.prev; var2.waitStatus > 0; var1.prev = var2 = var2.prev) {}AbstractQueuedSynchronizer.Node var3 = var2.next;var1.waitStatus = 1;if (var1 == this.tail && this.compareAndSetTail(var1, var2)) {compareAndSetNext(var2, var3, (AbstractQueuedSynchronizer.Node)null);} else {int var4;if (var2 != this.head && ((var4 = var2.waitStatus) == -1 || var4 <= 0 && compareAndSetWaitStatus(var2, var4, -1)) && var2.thread != null) {AbstractQueuedSynchronizer.Node var5 = var1.next;if (var5 != null && var5.waitStatus <= 0) {compareAndSetNext(var2, var3, var5);}} else {this.unparkSuccessor(var1);}var1.next = var1;}}}private static boolean shouldParkAfterFailedAcquire(AbstractQueuedSynchronizer.Node var0, AbstractQueuedSynchronizer.Node var1) {int var2 = var0.waitStatus;if (var2 == -1) {return true;} else {if (var2 > 0) {do {var1.prev = var0 = var0.prev;} while(var0.waitStatus > 0);var0.next = var1;} else {compareAndSetWaitStatus(var0, var2, -1);}return false;}}static void selfInterrupt() {Thread.currentThread().interrupt();}private final boolean parkAndCheckInterrupt() {LockSupport.park(this);return Thread.interrupted();}final boolean acquireQueued(AbstractQueuedSynchronizer.Node var1, int var2) {boolean var3 = true;try {boolean var4 = false;while(true) {AbstractQueuedSynchronizer.Node var5 = var1.predecessor();if (var5 == this.head && this.tryAcquire(var2)) {this.setHead(var1);var5.next = null;var3 = false;boolean var6 = var4;return var6;}if (shouldParkAfterFailedAcquire(var5, var1) && this.parkAndCheckInterrupt()) {var4 = true;}}} finally {if (var3) {this.cancelAcquire(var1);}}}private void doAcquireInterruptibly(int var1) throws InterruptedException {AbstractQueuedSynchronizer.Node var2 = this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE);boolean var3 = true;try {AbstractQueuedSynchronizer.Node var4;do {var4 = var2.predecessor();if (var4 == this.head && this.tryAcquire(var1)) {this.setHead(var2);var4.next = null;var3 = false;return;}} while(!shouldParkAfterFailedAcquire(var4, var2) || !this.parkAndCheckInterrupt());throw new InterruptedException();} finally {if (var3) {this.cancelAcquire(var2);}}}private boolean doAcquireNanos(int var1, long var2) throws InterruptedException {if (var2 <= 0L) {return false;} else {long var4 = System.nanoTime() + var2;AbstractQueuedSynchronizer.Node var6 = this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE);boolean var7 = true;try {do {AbstractQueuedSynchronizer.Node var8 = var6.predecessor();boolean var9;if (var8 == this.head && this.tryAcquire(var1)) {this.setHead(var6);var8.next = null;var7 = false;var9 = true;return var9;}var2 = var4 - System.nanoTime();if (var2 <= 0L) {var9 = false;return var9;}if (shouldParkAfterFailedAcquire(var8, var6) && var2 > 1000L) {LockSupport.parkNanos(this, var2);}} while(!Thread.interrupted());throw new InterruptedException();} finally {if (var7) {this.cancelAcquire(var6);}}}}private void doAcquireShared(int var1) {AbstractQueuedSynchronizer.Node var2 = this.addWaiter(AbstractQueuedSynchronizer.Node.SHARED);boolean var3 = true;try {boolean var4 = false;while(true) {AbstractQueuedSynchronizer.Node var5 = var2.predecessor();if (var5 == this.head) {int var6 = this.tryAcquireShared(var1);if (var6 >= 0) {this.setHeadAndPropagate(var2, var6);var5.next = null;if (var4) {selfInterrupt();}var3 = false;return;}}if (shouldParkAfterFailedAcquire(var5, var2) && this.parkAndCheckInterrupt()) {var4 = true;}}} finally {if (var3) {this.cancelAcquire(var2);}}}private void doAcquireSharedInterruptibly(int var1) throws InterruptedException {AbstractQueuedSynchronizer.Node var2 = this.addWaiter(AbstractQueuedSynchronizer.Node.SHARED);boolean var3 = true;try {AbstractQueuedSynchronizer.Node var4;do {var4 = var2.predecessor();if (var4 == this.head) {int var5 = this.tryAcquireShared(var1);if (var5 >= 0) {this.setHeadAndPropagate(var2, var5);var4.next = null;var3 = false;return;}}} while(!shouldParkAfterFailedAcquire(var4, var2) || !this.parkAndCheckInterrupt());throw new InterruptedException();} finally {if (var3) {this.cancelAcquire(var2);}}}private boolean doAcquireSharedNanos(int var1, long var2) throws InterruptedException {if (var2 <= 0L) {return false;} else {long var4 = System.nanoTime() + var2;AbstractQueuedSynchronizer.Node var6 = this.addWaiter(AbstractQueuedSynchronizer.Node.SHARED);boolean var7 = true;try {do {AbstractQueuedSynchronizer.Node var8 = var6.predecessor();if (var8 == this.head) {int var9 = this.tryAcquireShared(var1);if (var9 >= 0) {this.setHeadAndPropagate(var6, var9);var8.next = null;var7 = false;boolean var10 = true;return var10;}}var2 = var4 - System.nanoTime();if (var2 <= 0L) {boolean var14 = false;return var14;}if (shouldParkAfterFailedAcquire(var8, var6) && var2 > 1000L) {LockSupport.parkNanos(this, var2);}} while(!Thread.interrupted());throw new InterruptedException();} finally {if (var7) {this.cancelAcquire(var6);}}}}// 在AbstractQueuedSynchronizer中并没有实现,具体实现的逻辑都在子类中protected boolean tryAcquire(int var1) {throw new UnsupportedOperationException();}protected boolean tryRelease(int var1) {throw new UnsupportedOperationException();}protected int tryAcquireShared(int var1) {throw new UnsupportedOperationException();}protected boolean tryReleaseShared(int var1) {throw new UnsupportedOperationException();}protected boolean isHeldExclusively() {throw new UnsupportedOperationException();}public final void acquire(int var1) {//this.acquireQueued(this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE), var1)加锁失败强制入队if (!this.tryAcquire(var1) && this.acquireQueued(this.addWaiter(AbstractQueuedSynchronizer.Node.EXCLUSIVE), var1)) {selfInterrupt();}}public final void acquireInterruptibly(int var1) throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {if (!this.tryAcquire(var1)) {this.doAcquireInterruptibly(var1);}}}public final boolean tryAcquireNanos(int var1, long var2) throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {return this.tryAcquire(var1) || this.doAcquireNanos(var1, var2);}}public final boolean release(int var1) {if (this.tryRelease(var1)) {AbstractQueuedSynchronizer.Node var2 = this.head;if (var2 != null && var2.waitStatus != 0) {this.unparkSuccessor(var2);}return true;} else {return false;}}public final void acquireShared(int var1) {if (this.tryAcquireShared(var1) < 0) {this.doAcquireShared(var1);}}public final void acquireSharedInterruptibly(int var1) throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {if (this.tryAcquireShared(var1) < 0) {this.doAcquireSharedInterruptibly(var1);}}}public final boolean tryAcquireSharedNanos(int var1, long var2) throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {return this.tryAcquireShared(var1) >= 0 || this.doAcquireSharedNanos(var1, var2);}}public final boolean releaseShared(int var1) {if (this.tryReleaseShared(var1)) {this.doReleaseShared();return true;} else {return false;}}public final boolean hasQueuedThreads() {return this.head != this.tail;}public final boolean hasContended() {return this.head != null;}public final Thread getFirstQueuedThread() {return this.head == this.tail ? null : this.fullGetFirstQueuedThread();}private Thread fullGetFirstQueuedThread() {AbstractQueuedSynchronizer.Node var1;AbstractQueuedSynchronizer.Node var2;Thread var3;if (((var1 = this.head) == null || (var2 = var1.next) == null || var2.prev != this.head || (var3 = var2.thread) == null) && ((var1 = this.head) == null || (var2 = var1.next) == null || var2.prev != this.head || (var3 = var2.thread) == null)) {AbstractQueuedSynchronizer.Node var4 = this.tail;Thread var5;for(var5 = null; var4 != null && var4 != this.head; var4 = var4.prev) {Thread var6 = var4.thread;if (var6 != null) {var5 = var6;}}return var5;} else {return var3;}}public final boolean isQueued(Thread var1) {if (var1 == null) {throw new NullPointerException();} else {for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != null; var2 = var2.prev) {if (var2.thread == var1) {return true;}}return false;}}final boolean apparentlyFirstQueuedIsExclusive() {AbstractQueuedSynchronizer.Node var1;AbstractQueuedSynchronizer.Node var2;return (var1 = this.head) != null && (var2 = var1.next) != null && !var2.isShared() && var2.thread != null;}public final boolean hasQueuedPredecessors() {AbstractQueuedSynchronizer.Node var1 = this.tail;AbstractQueuedSynchronizer.Node var2 = this.head;AbstractQueuedSynchronizer.Node var3;return var2 != var1 && ((var3 = var2.next) == null || var3.thread != Thread.currentThread());}public final int getQueueLength() {int var1 = 0;for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != null; var2 = var2.prev) {if (var2.thread != null) {++var1;}}return var1;}public final Collection getQueuedThreads() {ArrayList var1 = new ArrayList();for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != null; var2 = var2.prev) {Thread var3 = var2.thread;if (var3 != null) {var1.add(var3);}}return var1;}public final Collection getExclusiveQueuedThreads() {ArrayList var1 = new ArrayList();for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != null; var2 = var2.prev) {if (!var2.isShared()) {Thread var3 = var2.thread;if (var3 != null) {var1.add(var3);}}}return var1;}public final Collection getSharedQueuedThreads() {ArrayList var1 = new ArrayList();for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != null; var2 = var2.prev) {if (var2.isShared()) {Thread var3 = var2.thread;if (var3 != null) {var1.add(var3);}}}return var1;}public String toString() {int var1 = this.getState();String var2 = this.hasQueuedThreads() ? "non" : "";return super.toString() + "[State = " + var1 + ", " + var2 + "empty queue]";}final boolean isOnSyncQueue(AbstractQueuedSynchronizer.Node var1) {if (var1.waitStatus != -2 && var1.prev != null) {return var1.next != null ? true : this.findNodeFromTail(var1);} else {return false;}}private boolean findNodeFromTail(AbstractQueuedSynchronizer.Node var1) {for(AbstractQueuedSynchronizer.Node var2 = this.tail; var2 != var1; var2 = var2.prev) {if (var2 == null) {return false;}}return true;}final boolean transferForSignal(AbstractQueuedSynchronizer.Node var1) {if (!compareAndSetWaitStatus(var1, -2, 0)) {return false;} else {AbstractQueuedSynchronizer.Node var2 = this.enq(var1);int var3 = var2.waitStatus;if (var3 > 0 || !compareAndSetWaitStatus(var2, var3, -1)) {LockSupport.unpark(var1.thread);}return true;}}final boolean transferAfterCancelledWait(AbstractQueuedSynchronizer.Node var1) {if (compareAndSetWaitStatus(var1, -2, 0)) {this.enq(var1);return true;} else {while(!this.isOnSyncQueue(var1)) {Thread.yield();}return false;}}final int fullyRelease(AbstractQueuedSynchronizer.Node var1) {boolean var2 = true;int var4;try {int var3 = this.getState();if (!this.release(var3)) {throw new IllegalMonitorStateException();}var2 = false;var4 = var3;} finally {if (var2) {var1.waitStatus = 1;}}return var4;}public final boolean owns(AbstractQueuedSynchronizer.ConditionObject var1) {return var1.isOwnedBy(this);}public final boolean hasWaiters(AbstractQueuedSynchronizer.ConditionObject var1) {if (!this.owns(var1)) {throw new IllegalArgumentException("Not owner");} else {return var1.hasWaiters();}}public final int getWaitQueueLength(AbstractQueuedSynchronizer.ConditionObject var1) {if (!this.owns(var1)) {throw new IllegalArgumentException("Not owner");} else {return var1.getWaitQueueLength();}}public final Collection getWaitingThreads(AbstractQueuedSynchronizer.ConditionObject var1) {if (!this.owns(var1)) {throw new IllegalArgumentException("Not owner");} else {return var1.getWaitingThreads();}}private final boolean compareAndSetHead(AbstractQueuedSynchronizer.Node var1) {return unsafe.compareAndSwapObject(this, headOffset, (Object)null, var1);}private final boolean compareAndSetTail(AbstractQueuedSynchronizer.Node var1, AbstractQueuedSynchronizer.Node var2) {return unsafe.compareAndSwapObject(this, tailOffset, var1, var2);}private static final boolean compareAndSetWaitStatus(AbstractQueuedSynchronizer.Node var0, int var1, int var2) {return unsafe.compareAndSwapInt(var0, waitStatusOffset, var1, var2);}private static final boolean compareAndSetNext(AbstractQueuedSynchronizer.Node var0, AbstractQueuedSynchronizer.Node var1, AbstractQueuedSynchronizer.Node var2) {return unsafe.compareAndSwapObject(var0, nextOffset, var1, var2);}static {try {stateOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("state"));headOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("head"));tailOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.class.getDeclaredField("tail"));waitStatusOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.Node.class.getDeclaredField("waitStatus"));nextOffset = unsafe.objectFieldOffset(AbstractQueuedSynchronizer.Node.class.getDeclaredField("next"));} catch (Exception var1) {throw new Error(var1);}}public class ConditionObject implements Condition, Serializable {private static final long serialVersionUID = 1173984872572414699L;private transient AbstractQueuedSynchronizer.Node firstWaiter;private transient AbstractQueuedSynchronizer.Node lastWaiter;private static final int REINTERRUPT = 1;private static final int THROW_IE = -1;public ConditionObject() {}private AbstractQueuedSynchronizer.Node addConditionWaiter() {AbstractQueuedSynchronizer.Node var1 = this.lastWaiter;if (var1 != null && var1.waitStatus != -2) {this.unlinkCancelledWaiters();var1 = this.lastWaiter;}AbstractQueuedSynchronizer.Node var2 = new AbstractQueuedSynchronizer.Node(Thread.currentThread(), -2);if (var1 == null) {this.firstWaiter = var2;} else {var1.nextWaiter = var2;}this.lastWaiter = var2;return var2;}private void doSignal(AbstractQueuedSynchronizer.Node var1) {do {if ((this.firstWaiter = var1.nextWaiter) == null) {this.lastWaiter = null;}var1.nextWaiter = null;} while(!AbstractQueuedSynchronizer.this.transferForSignal(var1) && (var1 = this.firstWaiter) != null);}private void doSignalAll(AbstractQueuedSynchronizer.Node var1) {this.lastWaiter = this.firstWaiter = null;AbstractQueuedSynchronizer.Node var2;do {var2 = var1.nextWaiter;var1.nextWaiter = null;AbstractQueuedSynchronizer.this.transferForSignal(var1);var1 = var2;} while(var2 != null);}private void unlinkCancelledWaiters() {AbstractQueuedSynchronizer.Node var1 = this.firstWaiter;AbstractQueuedSynchronizer.Node var3;for(AbstractQueuedSynchronizer.Node var2 = null; var1 != null; var1 = var3) {var3 = var1.nextWaiter;if (var1.waitStatus != -2) {var1.nextWaiter = null;if (var2 == null) {this.firstWaiter = var3;} else {var2.nextWaiter = var3;}if (var3 == null) {this.lastWaiter = var2;}} else {var2 = var1;}}}public final void signal() {if (!AbstractQueuedSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {AbstractQueuedSynchronizer.Node var1 = this.firstWaiter;if (var1 != null) {this.doSignal(var1);}}}public final void signalAll() {if (!AbstractQueuedSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {AbstractQueuedSynchronizer.Node var1 = this.firstWaiter;if (var1 != null) {this.doSignalAll(var1);}}}public final void awaitUninterruptibly() {AbstractQueuedSynchronizer.Node var1 = this.addConditionWaiter();int var2 = AbstractQueuedSynchronizer.this.fullyRelease(var1);boolean var3 = false;while(!AbstractQueuedSynchronizer.this.isOnSyncQueue(var1)) {LockSupport.park(this);if (Thread.interrupted()) {var3 = true;}}if (AbstractQueuedSynchronizer.this.acquireQueued(var1, var2) || var3) {AbstractQueuedSynchronizer.selfInterrupt();}}private int checkInterruptWhileWaiting(AbstractQueuedSynchronizer.Node var1) {return Thread.interrupted() ? (AbstractQueuedSynchronizer.this.transferAfterCancelledWait(var1) ? -1 : 1) : 0;}private void reportInterruptAfterWait(int var1) throws InterruptedException {if (var1 == -1) {throw new InterruptedException();} else {if (var1 == 1) {AbstractQueuedSynchronizer.selfInterrupt();}}}public final void await() throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {AbstractQueuedSynchronizer.Node var1 = this.addConditionWaiter();int var2 = AbstractQueuedSynchronizer.this.fullyRelease(var1);int var3 = 0;while(!AbstractQueuedSynchronizer.this.isOnSyncQueue(var1)) {LockSupport.park(this);if ((var3 = this.checkInterruptWhileWaiting(var1)) != 0) {break;}}if (AbstractQueuedSynchronizer.this.acquireQueued(var1, var2) && var3 != -1) {var3 = 1;}if (var1.nextWaiter != null) {this.unlinkCancelledWaiters();}if (var3 != 0) {this.reportInterruptAfterWait(var3);}}}public final long awaitNanos(long var1) throws InterruptedException {if (Thread.interrupted()) {throw new InterruptedException();} else {AbstractQueuedSynchronizer.Node var3 = this.addConditionWaiter();int var4 = AbstractQueuedSynchronizer.this.fullyRelease(var3);long var5 = System.nanoTime() + var1;int var7;for(var7 = 0; !AbstractQueuedSynchronizer.this.isOnSyncQueue(var3); var1 = var5 - System.nanoTime()) {if (var1 <= 0L) {AbstractQueuedSynchronizer.this.transferAfterCancelledWait(var3);break;}if (var1 >= 1000L) {LockSupport.parkNanos(this, var1);}if ((var7 = this.checkInterruptWhileWaiting(var3)) != 0) {break;}}if (AbstractQueuedSynchronizer.this.acquireQueued(var3, var4) && var7 != -1) {var7 = 1;}if (var3.nextWaiter != null) {this.unlinkCancelledWaiters();}if (var7 != 0) {this.reportInterruptAfterWait(var7);}return var5 - System.nanoTime();}}public final boolean awaitUntil(Date var1) throws InterruptedException {long var2 = var1.getTime();if (Thread.interrupted()) {throw new InterruptedException();} else {AbstractQueuedSynchronizer.Node var4 = this.addConditionWaiter();int var5 = AbstractQueuedSynchronizer.this.fullyRelease(var4);boolean var6 = false;int var7 = 0;while(!AbstractQueuedSynchronizer.this.isOnSyncQueue(var4)) {if (System.currentTimeMillis() > var2) {var6 = AbstractQueuedSynchronizer.this.transferAfterCancelledWait(var4);break;}LockSupport.parkUntil(this, var2);if ((var7 = this.checkInterruptWhileWaiting(var4)) != 0) {break;}}if (AbstractQueuedSynchronizer.this.acquireQueued(var4, var5) && var7 != -1) {var7 = 1;}if (var4.nextWaiter != null) {this.unlinkCancelledWaiters();}if (var7 != 0) {this.reportInterruptAfterWait(var7);}return !var6;}}public final boolean await(long var1, TimeUnit var3) throws InterruptedException {long var4 = var3.toNanos(var1);if (Thread.interrupted()) {throw new InterruptedException();} else {AbstractQueuedSynchronizer.Node var6 = this.addConditionWaiter();int var7 = AbstractQueuedSynchronizer.this.fullyRelease(var6);long var8 = System.nanoTime() + var4;boolean var10 = false;int var11;for(var11 = 0; !AbstractQueuedSynchronizer.this.isOnSyncQueue(var6); var4 = var8 - System.nanoTime()) {if (var4 <= 0L) {var10 = AbstractQueuedSynchronizer.this.transferAfterCancelledWait(var6);break;}if (var4 >= 1000L) {LockSupport.parkNanos(this, var4);}if ((var11 = this.checkInterruptWhileWaiting(var6)) != 0) {break;}}if (AbstractQueuedSynchronizer.this.acquireQueued(var6, var7) && var11 != -1) {var11 = 1;}if (var6.nextWaiter != null) {this.unlinkCancelledWaiters();}if (var11 != 0) {this.reportInterruptAfterWait(var11);}return !var10;}}final boolean isOwnedBy(AbstractQueuedSynchronizer var1) {return var1 == AbstractQueuedSynchronizer.this;}protected final boolean hasWaiters() {if (!AbstractQueuedSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {for(AbstractQueuedSynchronizer.Node var1 = this.firstWaiter; var1 != null; var1 = var1.nextWaiter) {if (var1.waitStatus == -2) {return true;}}return false;}}protected final int getWaitQueueLength() {if (!AbstractQueuedSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {int var1 = 0;for(AbstractQueuedSynchronizer.Node var2 = this.firstWaiter; var2 != null; var2 = var2.nextWaiter) {if (var2.waitStatus == -2) {++var1;}}return var1;}}protected final Collection getWaitingThreads() {if (!AbstractQueuedSynchronizer.this.isHeldExclusively()) {throw new IllegalMonitorStateException();} else {ArrayList var1 = new ArrayList();for(AbstractQueuedSynchronizer.Node var2 = this.firstWaiter; var2 != null; var2 = var2.nextWaiter) {if (var2.waitStatus == -2) {Thread var3 = var2.thread;if (var3 != null) {var1.add(var3);}}}return var1;}}}static final class Node {static final AbstractQueuedSynchronizer.Node SHARED = new AbstractQueuedSynchronizer.Node();static final AbstractQueuedSynchronizer.Node EXCLUSIVE = null;static final int CANCELLED = 1;static final int SIGNAL = -1;static final int CONDITION = -2;static final int PROPAGATE = -3;volatile int waitStatus;volatile AbstractQueuedSynchronizer.Node prev;volatile AbstractQueuedSynchronizer.Node next;volatile Thread thread;AbstractQueuedSynchronizer.Node nextWaiter;final boolean isShared() {return this.nextWaiter == SHARED;}final AbstractQueuedSynchronizer.Node predecessor() throws NullPointerException {AbstractQueuedSynchronizer.Node var1 = this.prev;if (var1 == null) {throw new NullPointerException();} else {return var1;}}Node() {}Node(Thread var1, AbstractQueuedSynchronizer.Node var2) {this.nextWaiter = var2;this.thread = var1;}Node(Thread var1, int var2) {this.waitStatus = var2;this.thread = var1;}}
}

三、ReentrantLock

1.在ReentrantLock内部定义了一个Sync的内部类,该类继承AbstractQueuedSynchronized,对该抽象类的部分方法做了实现;
2.定义了两个子类:
1>FairSync 公平锁的实现
2>NonfairSync 非公平锁的实现
这两个类都继承自Sync,也就是间接继承了AbstractQueuedSynchronized,所以这一个ReentrantLock同时具备公平与非公平特性。

abstract static class Sync extends AbstractQueuedSynchronizer {private static final long serialVersionUID = -5179523762034025860L;Sync() {}abstract void lock();final boolean nonfairTryAcquire(int var1) {Thread var2 = Thread.currentThread();int var3 = this.getState();if (var3 == 0) {if (this.compareAndSetState(0, var1)) {this.setExclusiveOwnerThread(var2);return true;}} else if (var2 == this.getExclusiveOwnerThread()) {int var4 = var3 + var1;if (var4 < 0) {throw new Error("Maximum lock count exceeded");}this.setState(var4);return true;}return false;}protected final boolean tryRelease(int var1) {int var2 = this.getState() - var1;if (Thread.currentThread() != this.getExclusiveOwnerThread()) {throw new IllegalMonitorStateException();} else {boolean var3 = false;if (var2 == 0) {var3 = true;this.setExclusiveOwnerThread((Thread)null);}this.setState(var2);return var3;}}protected final boolean isHeldExclusively() {return this.getExclusiveOwnerThread() == Thread.currentThread();}final ConditionObject newCondition() {return new ConditionObject(this);}final Thread getOwner() {return this.getState() == 0 ? null : this.getExclusiveOwnerThread();}final int getHoldCount() {return this.isHeldExclusively() ? this.getState() : 0;}final boolean isLocked() {return this.getState() != 0;}private void readObject(ObjectInputStream var1) throws IOException, ClassNotFoundException {var1.defaultReadObject();this.setState(0);}}
 static final class FairSync extends ReentrantLock.Sync {private static final long serialVersionUID = -3000897897090466540L;FairSync() {}final void lock() {this.acquire(1);}protected final boolean tryAcquire(int var1) {Thread var2 = Thread.currentThread();int var3 = this.getState();if (var3 == 0) {if (!this.hasQueuedPredecessors() && this.compareAndSetState(0, var1)) {this.setExclusiveOwnerThread(var2);return true;}} else if (var2 == this.getExclusiveOwnerThread()) {int var4 = var3 + var1;if (var4 < 0) {throw new Error("Maximum lock count exceeded");}this.setState(var4);return true;}return false;}}static final class NonfairSync extends ReentrantLock.Sync {private static final long serialVersionUID = 7316153563782823691L;NonfairSync() {}final void lock() {if (this.compareAndSetState(0, 1)) {this.setExclusiveOwnerThread(Thread.currentThread());} else {this.acquire(1);}}protected final boolean tryAcquire(int var1) {return this.nonfairTryAcquire(var1);}}

相关内容

热门资讯

不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
报告实验.pdfbase.tt... 这个错误通常是由于找不到字体文件或者文件路径不正确导致的。以下是一些解决方法:确认字体文件是否存在:...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...