ReentrantLock 可重入锁
使用
class X {
private final ReentrantLock lock = new ReentrantLock();
public void m() {
lock.lock(); // block until condition holds
try {
// ... method body
} finally {
lock.unlock()
}
}
}}
加锁解锁源码分析
按序号看,1)表示加锁流程,1))表示解锁流程
public class ReentrantLock implements Lock, java.io.Serializable {
//锁
private final Sync sync;
//构造方法
//无参构造方法,给sync赋值非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
//有参构造方法,根据入参选择使用公平锁还是非公平锁
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
//加锁
//此处分析非公平锁
//调用成员变量的lock方法 下面的序号代表执行顺序
//1)
public void lock() {
sync.lock();
}
//解锁 1表示减少一次重入次数 1))
public void unlock() {
sync.release(1);
}
//继承aqs AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer 这么个继承关系
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();
//非公平锁的尝试获取锁方法 3-2-3)
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
//没有线程抢到锁,尝试加锁
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}//有线程抢到了锁,判断是否是当前线程,如果是,则将重入次数+1
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;
}
// 3))
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;
}
protected final boolean isHeldExclusively() {
// While we must in general read state before owner,
// we don't need to do so to check if current thread is owner
return getExclusiveOwnerThread() == Thread.currentThread();
}
final ConditionObject newCondition() {
return new ConditionObject();
}
// Methods relayed from outer class
final Thread getOwner() {
return getState() == 0 ? null : getExclusiveOwnerThread();
}
final int getHoldCount() {
return isHeldExclusively() ? getState() : 0;
}
final boolean isLocked() {
return getState() != 0;
}
/**
* Reconstitutes the instance from a stream (that is, deserializes it).
*/
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
setState(0); // reset to unlocked state
}
}
//非公平锁的静态内部类
static final class NonfairSync extends Sync {
//加锁方法 2)
final void lock() {
//设置成功表示抢到加锁权限,加锁成功 非公平锁体现,线程上来就抢锁,不管等待队列里面的线程
//3-1) 此处序号代表分支
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else//不成功,加锁 3-2)
acquire(1);
}
//非公平锁的尝试获取锁方法 3-2-2)
protected final boolean tryAcquire(int acquires) {
//调用非公平锁获得锁方法
return nonfairTryAcquire(acquires);
}
}
}
static final class FairSync extends Sync {
private static final long serialVersionUID = -3000897897090466540L;
//公平锁的lock方法,不会将Thread直接尝试获取锁,而是从aqs队列里面取节点取获取锁,性能比较低
final void lock() {
acquire(1);
}
//公平锁的获取锁方法
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//当前线程没有前驱节点才可以去获取锁
if (!hasQueuedPredecessors() &&
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
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;
//重入次数为0,则表示彻底释放了锁,将当前获得锁的线程置为空
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
//设置重入次数
setState(c);
return free;
}
}
public abstract class AbstractQueuedSynchronizer extends AbstractOwnableSynchronizer implements java.io.Serializable {
//aqs队列的头节点
private transient volatile Node head;
//aqs队列的尾节点
private transient volatile Node tail;
private volatile int state;
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;
volatile Node prev;
volatile Node next;
volatile Thread thread;
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
(Node.class.getDeclaredField("waitStatus"));
nextOffset = unsafe.objectFieldOffset
(Node.class.getDeclaredField("next"));
} catch (Exception ex) { throw new Error(ex); }
}
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
//AbstractOwnableSynchronizer 类的方法和属性,设置独占锁线程
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
// 获取锁 3-2-1)
public final void acquire(int arg) {
//尝试获取锁
//获取不到锁,则将该线程包装为独占节点添加到 aqs队列中 如果线程被中断过,则将线程中断,线程在aqs队列中的时候不响应中断
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
//中断线程
static void selfInterrupt() {
Thread.currentThread().interrupt();
}
// 获取状态
protected final int getState() {
return state;
}
// 设置状态
protected final void setState(int newState) {
state = newState;
}
//将当前线程包装成一个Node 3-2-4)
private Node addWaiter(Node mode) {
Node node = new Node(Thread.currentThread(), mode);
// 尝试快速入队,将该节点挂在aqs尾节点的的下一个节点 设置成功,该节点变成尾节点
Node pred = tail;
if (pred != null) {
node.prev = pred;
//cas设置尾节点
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
//快速入队失败,执行入队方法
enq(node);
return node;
}
//将节点设置为尾节点
private final boolean compareAndSetTail(Node expect, Node update) {
return unsafe.compareAndSwapObject(this, tailOffset, expect, update);
}
//入队方法 3-2-5)
private Node enq(final Node node) {
//自旋锁
for (;;) {
Node t = tail;
//aqs队列未初始化,初始化
if (t == null) { // Must initialize
if (compareAndSetHead(new Node()))
tail = head;
} else {//初始化过了 将该节点设置成尾节点,并将原来的尾节点指针指向新的尾节点
node.prev = t;
if (compareAndSetTail(t, node)) {
t.next = node;
return t;
}
}
}
}
//cas设置aqs队列的头节点
private final boolean compareAndSetHead(Node update) {
return unsafe.compareAndSwapObject(this, headOffset, null, update);
}
//入队 3-2-5)
final boolean acquireQueued(final Node node, int arg) {
boolean failed = true;
try {
boolean interrupted = false;
//自旋 如果没有挂起,达到一定次数,jdk会断掉自旋 然后走finally取消获取锁操作
for (;;) {
//获取上一个节点
final Node p = node.predecessor();
//上一个节点是头节点 并且 获取到了锁
if (p == head && tryAcquire(arg)) {
//将当前节点设置成头节点,原头节点删除 头节点是一个占位节点,里面的thread是null
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
//挂起线程
//挂起后,线程暂停,当线程被唤醒时,如果线程被中断过,则interrupted = true;
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
if (failed)//取消获取锁
cancelAcquire(node);
}
}
private void setHead(Node node) {
head = node;
node.thread = null;
node.prev = null;
}
//是否应该挂起
private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
int ws = pred.waitStatus;
if (ws == Node.SIGNAL)
//可以放心挂起
return true;
if (ws > 0) {
//遍历 将 CANCEL节点删除
do {
node.prev = pred = pred.prev;
} while (pred.waitStatus > 0);
pred.next = node;
} else {
//其他状态,将prev设置为signal
compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
}
return false;
}
//挂起线程 并返回线程是否被中断过
private final boolean parkAndCheckInterrupt() {
LockSupport.park(this);
//线程唤醒后 会返回
return Thread.interrupted();
}
//取消获取锁 上个方法中没有挂起,说明该节点
private void cancelAcquire(Node node) {
if (node == null)
return;
node.thread = null;
// aqs队列中移除CANCLE的节点
Node pred = node.prev;
while (pred.waitStatus > 0)
node.prev = pred = pred.prev;
Node predNext = pred.next;
//取消获取锁 将线程取消
node.waitStatus = Node.CANCELLED;
// 如果该节点是尾节点,直接去掉尾节点
if (node == tail && compareAndSetTail(node, pred)) {
compareAndSetNext(pred, predNext, null);
} else {
//将prev设置为signal
int ws;
if (pred != head &&
((ws = pred.waitStatus) == Node.SIGNAL ||
(ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) &&
pred.thread != null) {
Node next = node.next;
if (next != null && next.waitStatus <= 0)
compareAndSetNext(pred, predNext, next);
} else {//唤醒
unparkSuccessor(node);
}
node.next = node; // help GC
}
}
private static final boolean compareAndSetNext(Node node,
Node expect,
Node update) {
return unsafe.compareAndSwapObject(node, nextOffset, expect, update);
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
//如果头节点是signal,将其设置为状态0
if (ws < 0)
compareAndSetWaitStatus(node, ws, 0);
//找到距离头节点最近的为signal的节点(上一步已经将头节点设置为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);
}
private static final boolean compareAndSetWaitStatus(Node node,
int expect,
int update) {
return unsafe.compareAndSwapInt(node, waitStatusOffset,
expect, update);
}
public final boolean hasQueuedPredecessors() {
Node t = tail; // Read fields in reverse initialization order
Node h = head;
Node s;
return h != t &&
((s = h.next) == null || s.thread != Thread.currentThread());
}
//释放锁 2))
public final boolean release(int arg) {
//释放成功,唤醒线程
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
static final class Node {
//共享锁节点
static final Node SHARED = new Node();
//独占锁节点
static final Node EXCLUSIVE = null;
// 0 初始状态
//节点已取消 会从sqs队列中删除 该线程等待超时或被中断
static final int CANCELLED = 1;
//钱直接点释放锁,就会通知signal状态的后续节点的线程
static final int SIGNAL = -1;
//Condition节点
static final int CONDITION = -2;
//共享锁模式下,处于可运行状态
static final int PROPAGATE = -3;
volatile int waitStatus;
//aqs队列的前驱节点 aqs队列是双向链表
volatile Node prev;
//aqs队列的后继节点
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() { // Used to establish initial head or SHARED marker
}
Node(Thread thread, Node mode) { // Used by addWaiter
this.nextWaiter = mode;
this.thread = thread;
}
Node(Thread thread, int waitStatus) { // Used by Condition
this.waitStatus = waitStatus;
this.thread = thread;
}
}
}
public abstract class AbstractOwnableSynchronizer implements java.io.Serializable {
//当前获得锁的线程
private transient Thread exclusiveOwnerThread;
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
protected final Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;
}
}
图解
加锁流程图解
入队