版权声明:本文为博主原创文章,未经博主允许不得转载。http://mp.blog.csdn.net/configure#i https://blog.csdn.net/wangming520liwei/article/details/88092572
AQS(抽象的队列同步器)
ReetrantLock/CountDownLatch/Semaphore
先看CLH 队列
static final class Node {
/** 共享 */
static final Node SHARED = new Node();
/** 独占 */
static final Node EXCLUSIVE = null;
/**
* 因为超时或者中断,节点会被设置为取消状态,被取消的节点时不会参与到竞争中的,他会一直保持取消状态不会转变为其他状态;
*/
static final int CANCELLED = 1;
/**
* 后继节点的线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点的线程得以运行
*/
static final int SIGNAL = -1;
/**
* 节点在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()后,改节点将会从等待队列中转移到同步队列中,加入到同步状态的获取中
*/
static final int CONDITION = -2;
/**
* 表示下一次共享式同步状态获取将会无条件地传播下去
*/
static final int PROPAGATE = -3;
/** 等待状态 */
volatile int waitStatus;
/** 前驱节点 */
volatile Node prev;
/** 后继节点 */
volatile Node next;
/** 获取同步状态的线程 */
volatile Thread thread;
Node nextWaiter;
final boolean isShared() {
return nextWaiter == SHARED;
}
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
Node() {
}
Node(Thread thread, Node mode) {
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) {
this.waitStatus = waitStatus;
this.thread = thread;
}
}
CANCELLED:因为超时或者中断,结点会被设置为取消状态,被取消状态的结点不应该去竞争锁,只能保持取消状态不变,不能转换为其他状态。处于这种状态的结点会被踢出队列,被GC回收;
SIGNAL:表示这个结点的继任结点被阻塞了,到时需要通知它;
CONDITION:表示这个结点在条件队列中,因为等待某个条件而被阻塞;
PROPAGATE:使用在共享模式头结点有可能牌处于这种状态,表示锁的下一次获取可以无条件传播;
0:None of the above,新结点会处于这种状态。
再看AQS
// arg4 当前节点的前一个节点 arg0当前节点
if (shouldParkAfterFailedAcquire(arg4, arg0)
&& this.parkAndCheckInterrupt()) {
arg3 = true;
}
private final boolean parkAndCheckInterrupt() {
// 阻塞
LockSupport.park(this);
return Thread.interrupted();
}
private static boolean shouldParkAfterFailedAcquire(Node arg, Node arg0) {
// arg是当前节点arg0的前一个节点 是不是取消状态
int arg1 = arg.waitStatus;
if (arg1 == -1) {
//如果是,那么当前节点获得
return true;
} else {
if (arg1 > 0) {
do {
// 当前节点指向当前节点的前一个而节点的节点
arg0.prev = arg = arg.prev;
} while (arg.waitStatus > 0);
// 当前节点的下一个节点是当前节点
arg.next = arg0;
} else {
// 不是 -1 设置成取消状态
compareAndSetWaitStatus(arg, arg1, -1);
}
return false;
}
}
添加CLH队列
private Node addWaiter(Node arg0) {
// 当前节点
Node arg1 = new Node(Thread.currentThread(), arg0);
// arg2尾节点
Node arg2 = this.tail;
if (arg2 != null) {
// 当前节点的prev 指向尾巴节点
arg1.prev = arg2;
// 把当爱情呢节点设置成尾巴节点
if (this.compareAndSetTail(arg2, arg1)) {
// 尾节点的下一个节点是当前节点,返回当前节点
arg2.next = arg1;
return arg1;
}
}
// 循环加入当前节点
this.enq(arg1);
return arg1;
}
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
/**
* Performs {@link Lock#lock}. The main reason for subclassing
* is to allow fast path for nonfair version.
*/
abstract void lock();
/**
* Performs non-fair tryLock. tryAcquire is implemented in
* subclasses, but both need nonfair try for trylock method.
*/
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) // overflow
throw 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;
}