ReentrantLock是一个可重入且独占式的锁,该锁支持获取锁时的公平和非公平选择。
公平锁
公平锁遵循FIFO的原则,所有的线程都会顺序执行
获取锁
1 2 3 4 5 6 7 8 9 10 11 12
| final void lock() { acquire(1); }
public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
|
是否是获得锁,还是进入队列等待的逻辑在tryAcquire
函数里。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| 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; }
public final boolean hasQueuedPredecessors() { Node t = tail; Node h = head; Node s; return h != t && ((s = h.next) == null || s.thread != Thread.currentThread()); }
|
释放锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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; }
|
具体的释放逻辑在release
中,free代表该锁是否已完全释放锁,如果为true,AbstractQueuedSynchronizer继续执行release
,唤醒队列中的下一个节点;
false则该线程继续持有锁。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 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; }
|
非公平锁
非公平锁不会关注阻塞队列中是否还有线程,而是直接尝试获取锁,获取不到时在将线程加入到队列中。
获取锁
1 2 3 4 5 6 7 8 9 10 11 12 13
| final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } public final void acquire(int arg) { if (!tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }
|
非公平锁与公平锁的差别在于当c为0时,不去查询队列的状态,而是直接尝试修改state的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
|
非公平锁和共平锁的释放锁逻辑相同。