ReentranLock流程图
ReetrantLock & AQS源码分析
ReentrantLock本质是通过继承AQS来实现锁,而AQS则是通过两个核心内容来完成上锁的过程
1、CAS(比较交换算法)
2、volitile修饰的state状态,来确保锁的可见性
3、同步队列模型的双向链表
非公平锁实现
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
// 对当前锁状态进行对比,如果没有线程获取到锁,就自己持有(独占锁:写锁)
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
// 如果锁被获取了,就上一个锁被占用的状态,进行重试获取锁
acquire(1);
}
}
锁没有被获取的情况下,如何获取锁
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
// 获取当前锁状态内存偏移量与预期值(expect)进行对比,如果相同就证明当前锁没有被进行持有,则修改当前锁状态。
// compareAndSwapInt本地方法库
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env,
jobject unsafe, jobject obj, jlong offset, jint e, jint x))
UnsafeWrapper("Unsafe_CompareAndSwapInt");
oop p = JNIHandles::resolve(obj);
jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
protected final void setExclusiveOwnerThread(Thread thread) {
// 设置锁被当前线程持有
exclusiveOwnerThread = thread;
}
锁已经被占有的情况下
public final void acquire(int arg) {
// 以独占模式获取,忽略中断。 通过调用至少一次 tryAcquire 来实现,成功返回
// 否则线程排队,可能重复阻塞和解除阻塞
// 调用 tryAcquire 直到成功。
// 尝试获取锁,如果没有获取到就将当前线程加入到双向队列中.
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
// 通知前线程的中断(实际不会)
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
final boolean nonfairTryAcquire(int acquires) {
// 获取当前线程
final Thread current = Thread.currentThread();
// 判断当前锁是否被持有
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
// 判断当前线程是否持有锁,
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;
}
private Node addWaiter(Node mode) {
//
Node node = new Node(Thread.currentThread(), mode);
// 获取尾节点,如果有的话就将 当前线程节点与尾节点进行关联
Node pred = tail;
if (pred != null) {
node.prev = pred;
if (compareAndSetTail(pred, node)) {
pred.next = node;
return node;
}
}
// 将当前线程节点,放到队尾
enq(node);
return node;
}
final boolean acquireQueued(final Node node, int arg) {
/// 将当前线程入队了的节点,且设置状态为 1
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
// 获取当前线程节点的前置节点
final Node p = node.predecessor();
// 如果前置节点是 头节点,就尝试获取锁 (这个里的head 就是已经获取了锁的线程)
if (p == head && tryAcquire(arg)) {
// 并设置同步队列头为当前节点
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&
parkAndCheckInterrupt())
interrupted = true;
}
} finally {
// 如果一直没有获取锁
if (failed)
// 取消当前线程获取请求
cancelAcquire(node);
}
}