非公平锁LOCK方法
final void lock() {
if (compareAndSetState(0, 1)) // 尝试通过CAS的方式将state设1
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); // 获取所资源
}
AQS(AbstractQueuedSynchronizer)
内部维护了个由Node类组成的双向链表结构.
并且由state
标识当前锁资源是否被占有,大于0就代表有线程占有了资源
// AQS链表头节点
private transient volatile Node head;
// 尾部节点
private transient volatile Node tail;
// 每次有线程获取锁,state加1,大于0就代表有线程占有了资源
private volatile int state;
// 当前占有所资源的线程
private transient Thread exclusiveOwnerThread;
public final void acquire(int arg) {
if (!tryAcquire(arg) && // 如果没获取到锁,
acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
selfInterrupt();
}
}
非公平锁尝试获取所资源
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
// 通过CAS的方式将state从0修改为1,返回true代表修改成功,
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;
}
获取所资源失败,创建新的节点
private Node addWaiter(Node mode) {
// 创建节点并设置线程为当前线程,还有排他锁
Node node = new Node(Thread.currentThread(), mode);
// Try the fast path of enq; backup to full enq on failure
Node pred = tail;
if (pred != null) {
node.prev = pred; // 插入到双向链表的尾部
if (compareAndSetTail(pred, node)) { // 基于cas将刚创建的节点设为尾部节点
pred.next = node;
return node;
}
}
enq(node);
return node;
}
找当前节点的上一个节点,再次尝试获取锁,或者挂起
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor(); // 获取当前节点的上一个节点
if (p == head && tryAcquire(arg)) { // 如果我是头节点的后一个节点,尝试获取锁资源
setHead(node); // 获取锁资源成功后,当前节点设为头节点
p.next = null; // help GC
failed = false;
return interrupted; // 不挂起
}
if (shouldParkAfterFailedAcquire(p, node) && // 找到前面的有效节点
parkAndCheckInterrupt()) // 基于Unsafe类的park方法,将线程挂起
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
Node节点
public class Node {
// 排他锁标识
static final Node EXCLUSIVE = null;
// 失效
static final int CANCELLED = 1;
// 有这标识,代表后继节点需要被唤醒
static final int SIGNAL = -1;
static final int CONDITION = -2;
static final int PROPAGATE = -3;
// Node对象存储标识的地方
volatile int waitStatus;
// 上一个节点,前驱节点
volatile Node prev;
// 下一个节点,后继节点
volatile Node next;
// 当前节点绑定的线程
volatile Thread thread;
private Node nextWaiter;
final Node predecessor() throws NullPointerException {
Node p = prev;
if (p == null)
throw new NullPointerException();
else
return p;
}
}