Java并发之lock源码分析
程序员自己管理锁的释放
lock()方法
final void lock() {
//判断当前锁的状态,即STATE的是否为0,如果是0的话就将state改为1,表示当前锁空闲,当前线程抢占成功
if (compareAndSetState(0, 1))
//将当前线程记录
setExclusiveOwnerThread(Thread.currentThread());
else
//如果STATE不是0,代表此时锁还在被占用
//调用acquire(1);方法
acquire(1);
}
acquire(1)方法
//该方法进行了tryAcquire(arg)以及acquireQueued(addWaiter(Node.EXCLUSIVE), arg)判断
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
nonfairTryAcquire(1)方法
/**
线程掉用该方法时有3三种情况
1、当前锁没有被线程占用,当前线程获得锁资源,返回true
2、当前锁被线程占用,并且当前线程刚好是占用锁的那个线程,即锁的重入,会将state+1,并且返回true
3、锁被占用,并且不是当前线程占用的,就返回false
*/
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
//得到当前锁的State
int c = getState();
//判断state是否为0
if (c == 0) {
//如果是0就尝试抢占
if (compareAndSetState(0, acquires)) {
//抢占成功就返回true
setExclusiveOwnerThread(current);
return true;
}
}
//state不为0,以为当前锁是被占用的
//判断当前线程是否是已经获得锁的线程
else if (current == getExclusiveOwnerThread()) {
//如果是就把state加上1,并且当此时state+1的结果超出了state的最大正整数会抛出异常
int nextc = c + acquires;
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
//设置state
setState(nextc);
return true;
}
return false;
}
acquireQueued(addWaiter(Node.EXCLUSIVE), arg) 方法
- addWaiter(Node.EXCLUSIVE)方法
/**
将最新线程的NOde加入到等待队列中去
*/
private Node addWaiter(Node mode) {
//新建一个节点,节点中的Thread为当前线程,模式为排他模式,即排他锁
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;
//AQS原子性的设置新的尾结点
if (compareAndSetTail(pred, node)) {
构建好双向链表
pred.next = node;
return node;
}
}
//第一次会初始化head、tail并且赋值为空,再新建一个空的节点作为头
enq(node);
return node;
}
acquireQueued(final Node node, int arg)
/**
调用该方法的前提是,当前线程没有获得锁,并且已经将该线程防放置到等待队列里面自旋,知道等到自己获得锁才会出来
*/
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)) {
//是头结点并且获得了锁
//释放等待队列中,并且返回一个FALSE
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//判断线程是否需要中断
//shouldParkAfterFailedAcquire()方法返回值有两种可能
//true 如果当前的prev的waitstatus为0就返回true
//false 如果当前prev的waitstatus不为0就循环遍历去除不需要等待的线程节点
//AQS将节点的waitstatus变成signel
//如果返回true会将线程挂起处于阻塞状态
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
unlock()方法
release()方法
public final boolean release(int arg) {
if (tryRelease(arg)) {
//释放锁成功
Node h = head;
if (h != null && h.waitStatus != 0)
//唤醒
unparkSuccessor(h);
return true;
}
return false;
}
tryRelease(int releases)
/**
尝试断开锁,放回true就是锁释放成功,否则就返回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);
}
//更新将state
setState(c);
return free;
}
unparkSuccessor(Node node)
private void unparkSuccessor(Node node) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws = node.waitStatus;
if (ws < 0)
//将waitStatus更新为0
compareAndSetWaitStatus(node, ws, 0);
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
Node s = node.next;
//去死皮,从尾结点遍历,防止线程节点插入式破坏链表结构
if (s == null || s.waitStatus > 0) {
s = null;
for (Node t = tail; t != null && t != node; t = t.prev)
if (t.waitStatus <= 0)
s = t;
}
if (s != null)
//接触当前线程挂起状态
LockSupport.unpark(s.thread);
}