1、ReentrantLock
1.1 加锁流程源码
1.1.1 加锁流程概述
1.1.2 lock源码分析
1.1.2.1 公平和非公平锁方式
// 非公平锁
final void lock() {// 上来就先基于CAS的方式,尝试将state从0改为1if (compareAndSetState(0, 1))// 获取锁资源成功,会将当前线程设置到exclusiveOwnerThread属性,代表是当前线程持有着锁资源setExclusiveOwnerThread(Thread.currentThread());else// 执行acquire,尝试获取锁资源acquire(1);
}// 公平锁
final void lock() {// 执行acquire,尝试获取锁资源acquire(1);
}
1.1.2.2 acquire方法
public final void acquire(int arg) {// tryAcquire:再次查看,当前线程是否可以尝试获取锁资源if (!tryAcquire(arg) &&// 没有拿到锁资源// addWaiter(Node.EXCLUSIVE):将当前线程封装为Node节点,插入到AQS的双向链表的结尾// acquireQueued:查看我是否是第一个排队的节点,如果是可以再次尝试获取锁资源,如果长时间拿不到,挂起线程// 如果不是第一个排队的额节点,就尝试挂起线程即可acquireQueued(addWaiter(Node.EXCLUSIVE), arg))// 中断线程的操作selfInterrupt();
}
1.1.2.3 tryAcquire方法
// 非公平锁实现
final boolean nonfairTryAcquire(int acquires) {// 获取当前线程final Thread current = Thread.currentThread();// 获取了state熟属性int c = getState();// 判断state当前是否为0,之前持有锁的线程释放了锁资源if (c == 0) {// 再次抢一波锁资源if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);// 拿锁成功返回truereturn true;}}// 不是0,有线程持有着锁资源,如果是,证明是锁重入操作else if (current == getExclusiveOwnerThread()) {// 将state + 1int nextc = c + acquires;if (nextc < 0) // 说明对重入次数+1后,超过了int正数的取值范围// 01111111 11111111 11111111 11111111// 10000000 00000000 00000000 00000000// 说明重入的次数超过界限了。throw new Error("Maximum lock count exceeded");// 正常的将计算结果,复制给statesetState(nextc);// 锁重入成功return true;}// 返回falsereturn false;
}// 公平锁实现
protected final boolean tryAcquire(int acquires) {// 获取当前线程final Thread current = Thread.currentThread();// ....int c = getState();if (c == 0) {// 查看AQS中是否有排队的Node// 没人排队抢一手 。有人排队,如果我是第一个,也抢一手if (!hasQueuedPredecessors() &&// 抢一手~