ReentrantLock lock = new ReentrantLock();
lock.lock();
lock.unlock();
//ReentrantLock 源码中的使用
class X {
//实例化 ReentrantLock时,
//如果添加boolean参数,
//true是公平模式,
//flase是非公平模式,
//默认非公平,非公平模式下新来的线程并不一定就能先拿到锁,后来的也并不一定是后拿到锁
ReentrantLock lock = new ReentrantLock();
public void m() {
lock.lock();
try {
// ... method body
} finally {
lock.unlock();
}
}
}
//公平模式 下的lock,直接进行 acquire操作
final void lock() {
acquire(1);
}
// 非公平模式 下的lock,
//会先 根据 compareAndSetState 方法返回的结果,
//去尝试把当前线程设置成为 独占所有者线程,
//如果不成功再进行 acquire操作。
final void lock() {
//compareAndSetState 根据cas 设置,
//如果当前状态值等于期望值,
//则将同步状态设置为给定的更新值。
//compareAndSetState(0, 1)) 预期值为0,修改值为1,
//如果现在的state值为0,就把state值设置为1,
//把当前线程设置独占所有。
if (compareAndSetState(0, 1))
//把当前线程设置为 独占所有者线程
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
//采用独占模式,忽略中断。
//处理没有获取到锁的线程
//tryAcquire:重新 获取 一次锁和进行锁重入的处理。
//addWaiter:将线程添加到 同步 队列中。
//acquireQueued:自旋 获取 锁。
//selfInterrupt:中断线程。
//三个条件的 为and,如果 acquireQueued方法 返回true,selfInterrupt会中断线程
public final void acquire(int arg) {
if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();//中断线程
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
//执行不公平的tryLock。
//tryAcquire是在子类中实现的,但都需要不公平的尝试trylock方法。
final boolean nonfairTryAcquire(int acquires) {
//获取当前线程
final Thread current = Thread.currentThread();
//获取state的值
int c = getState();
//如果state的值为空,说明没有人使用锁
//如果预期值 为0,设置state为 设置值
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
//如果state的值不是0,判断 独占所有者线程 是否为自己,
//如果 独占所有者线程 是自己,state的值加上 要修改的值
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;
}
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 int waitStatus;
}
// 为当前线程和给定的模式创建节点
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
Node pred = tail;
if (pred != null) {
//如果 尾节点 不为null
//设置当前新创建节点的 前驱 节点为 尾节点
node.prev = pred;
//判断当前状态值是否等于预期的尾节点pred
//如果 预期值 尾节点 等于就将当前同步状态值更新尾节点为node
if (compareAndSetTail(pred, node)) {
//尾节点的后继结点为 新创建的节点
pred.next = node;
return node;
}
}
enq(node);
return node;
}
private Node enq(final Node node) {
for (;;) {
//获取尾节点
Node t = tail;
if (t == null) {
//初始化同步队列
// 创建新的节点new node()作为头节点
//把 头节点 作为尾节点
//而此时队列的尾节点和头结点是同一个节点
//由于enq是一个死循环,会再次进入判断 尾节点是否为空,
//已经设置 头节点和尾节点,进入else语句
if (compareAndSetHead(new Node()))
tail = head;
} else {
//尾节点不为空,把传入的node的 前驱 节点设置为尾节点
node.prev = t;
if (compareAndSetTail(t, node)) {
//判断node节点是否是预期的尾节点t,如果是就更新尾节点t为node,
//把 t 的后继节点设置为 传入的节点,此时的 尾节点为 传入的node
t.next = node;
return t;
}
}
}
}
//以死循环的方式不停的获取同步状态
//如果获取不到则阻塞节点中的线程,
//而被阻塞线程只能依靠其前驱节点的出队列操作或者阻塞线程中断
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
//获取 node节点的 前驱节点
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
//如果传入node节点的前驱节点为head,并且
//当前 线程还能够获得到 锁,就把传入node节点,设置为head
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
// shouldParkAfterFailedAcquire检查并更新未能获取的节点的状态
//parkAndCheckInterrupt 阻塞当前线程,暂停线程的轮询。
//当Unlock时会做后续节点的Unpark唤醒线程继续争抢锁。
if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)//取消正在进行的获取尝试
cancelAcquire(node);
}
}
//检查并更新未能获取的节点的状态,
//首先检查一下当前Node的前置节点pred是否是SIGNAL
//如果是SIGNAL,那么证明前置Node的线程已经Park了,
//如果waitStatus>0,那么当前节点已经Concel或者中断。
//那么不断调整当前节点的前置节点,将已经Concel的和已经中断的线程移除队列。
//如果waitStatus<0,那么设置waitStatus为SIGNAL,
//因为调用shouldParkAfterFailedAcquire的方法为死循环调用,所以终将返回true。
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
//如果线程阻塞,则返回true。
return true;
if (ws > 0) {
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
//判断pred节点的waitStatus值,是否为预期的ws
//如果是就更新 为 Node.SIGNAL,阻塞pred
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
lock.unlock();
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;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
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);
}
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;
}