1,概述
ReentrantLock对于线程经常使用lock和unlock方法来调整线程的状态。下面将对ReentrantLock的源码进行详解,来了解ReentrantLock底层是如何使用AQS,并且了解线程底层具体运行的一个状态。
2,源码解读
环境:jdk 1.8
测试代码
public class Test001 {
public static void main(String[] args) {
ReentrantLock reentrantLock = new ReentrantLock();
reentrantLock.lock(); // @1
System.out.printf("业务逻辑");
// reentrantLock.lock(); //@A 探究具体源码状态
reentrantLock.unlock();
}
}
在@1出断点
进入ReentrantLock
public void lock() {
sync.lock();
}
final void lock() {
if (compareAndSetState(0, 1)) //通过CAS原理,把当前线程的state状态从0改1
setExclusiveOwnerThread(Thread.currentThread()); // @2
else
acquire(1);
}
继续 查看这个CAS方法 进入AbstractQueuedSynchronizer ,底层使用的Unsafe来做CAS
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
修改完之后回到ReentrantLock @2中
setExclusiveOwnerThread(Thread.currentThread()); 意思就是设置当前线程为独占线程,
此方法是AbstractQueuedSynchronizer 的父类AbstractOwnableSynchronizer
protected final void setExclusiveOwnerThread(Thread thread) {
exclusiveOwnerThread = thread;
}
自此 lock方法处理完毕,
来看下unlock 进入ReentrantLock
public void unlock() {
sync.release(1);//这个参数就是刚刚我们修改的state,他是被volatile 修饰的int类型
}
进入AQS的release方法`
public final boolean release(int arg) {
if (tryRelease(arg)) {//arg=1
Node h = head; //head=null
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;//返回true
}
return false;
}
进入ReentrantLock 的tryRelease
protected final boolean tryRelease(int releases) {
int c = getState() - releases; //@1这里计算后C为0
if (Thread.currentThread() != getExclusiveOwnerThread())//@2
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {//c=0进入
free = true;
setExclusiveOwnerThread(null);//@3把当前线程清除
}
setState(c); // 此时变为0
return free; //返回一个true
}
@1AbstractQueuedSynchronizer
protected final int getState() {
return state; //状态已经在我们lock时变为1
}
@2 AbstractOwnableSynchronizer中
protected final Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;//之前我们lock时已经把当前线程设置到此处 查看上述代码
}
@3 AbstractOwnableSynchronizer中
protected final void setExclusiveOwnerThread(Thread thread) { //tread=null
exclusiveOwnerThread = thread;
}
自此unlock状态结束
想要查看具体这个state的状态,还有node节点问题,打开@A注释 。此时注意两次调用lock看下下面的状态
public void lock() {
sync.lock();
}
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1); //已经lock了一次state变为1,测试 肯定走这个方法
}
进入AbstractQueuedSynchronizer
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//
selfInterrupt();
}
进入ReentrantLock
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) { //1
final Thread current = Thread.currentThread();//获取当前线程
int c = getState(); //1
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {//@1
int nextc = c + acquires; //2
if (nextc < 0) // overflow
throw new Error("Maximum lock count exceeded");
setState(nextc);//设置到state中
return true;
}
return false;
}
@1AbstractOwnableSynchronizer
protected final Thread getExclusiveOwnerThread() {
return exclusiveOwnerThread;
}
自此查看到state状态由1变为2,并且查看unlock方法又变为1
3,总结
再看下AQS中
private transient volatile Node head;//头结点
/**
* Tail of the wait queue, lazily initialized. Modified only via
* method enq to add new wait node.
*/
private transient volatile Node tail; /尾巴结点
/**
* The synchronization state.
*/
private volatile int state; //状态state
可以看出如上原理 node结点一个双向链表,每个node存入的是线程,整个链表形成一个线程的等待队列。每个node就是一个线程。
state参数 主要由不同的类自身决定如ReentrantLock,原理就是通过CAS+volatile来修改state的值,当有重入现象,state会加一,当线程被释放之后,state会减一最后到0。