AbstractQueuedSynchronizer:抽象的同步队列
ReentrantLock -> 底层使用AQS
线程级别的锁:suchronized Lock
进程级别的锁:需要特定的中间件来解决(分布式锁)
阻塞和唤醒
wait/notify(无法实现指定线程的唤醒)
sleep 阻塞,定时器
condition(Condition队列,AQS队列)
Locksupport
park()阻塞当前线程
unpark(thread)唤醒指定线程
J.U.C Unsafe类
lock必须实现的三个机制
1.实现互斥锁的抢占
2.要将没有获取锁的线程加入到队列
3.没有获得锁的线程需要阻塞等待
加锁逻辑
//Nonfair不公平锁 ->
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
final void lock() {
//cas操作
if (compareAndSetState(0, 1))
//锁抢占,设置当前线程获得了锁
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
public final void acquire(int arg) {
if (!tryAcquire(arg) &&//尝试抢占一次,如果失败,继续往下
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//添加到队列
selfInterrupt();
}
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) {
boolean failed = true;
try {
boolean interrupted = false;
for (;;) {
final Node p = node.predecessor();
if (p == head && tryAcquire(arg)) {
setHead(node);
p.next = null; // help GC
failed = false;
return interrupted;
}
if (shouldParkAfterFailedAcquire(p, node) &&//对每个节点的状态进行判断,设置线程的状态
parkAndCheckInterrupt())//LockSupport.park(this);阻塞当前线程
interrupted = true;
}
} finally {
if (failed)
cancelAcquire(node);
}
}
释放锁逻辑
//Lock.unlock()释放锁
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;
}
private void unparkSuccessor(Node node) {
int ws = node.waitStatus;
if (ws < 0)
compareAndSetWaitStatus(node, ws, 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);
}
1.cas操作,抢占锁,compareAndSetState(0, 1)
2.修改成功,标识抢占锁成功,记录当前只有锁的线程
3.否则
3.1.尝试重新获取锁,cas操作
3.2.如果是锁重入,记录重入次数
3.3.以上都不是返回false
4.1.如果返回的是false,那么会添加当前线程到队列中