AbstractQueuedSynchronizer:抽象的同步队列
    ReentrantLock -> 底层使用AQS
    线程级别的锁:suchronized Lock
    进程级别的锁:需要特定的中间件来解决(分布式锁)

    阻塞和唤醒
    wait/notify(无法实现指定线程的唤醒)
    sleep 阻塞,定时器
    condition(Condition队列,AQS队列)
    Locksupport
    park()阻塞当前线程
    unpark(thread)唤醒指定线程
    J.U.C Unsafe类

    lock必须实现的三个机制
    1.实现互斥锁的抢占
    2.要将没有获取锁的线程加入到队列
    3.没有获得锁的线程需要阻塞等待

    image.png

    加锁逻辑

    1. //Nonfair不公平锁 ->
    2. static final class NonfairSync extends Sync {
    3. private static final long serialVersionUID = 7316153563782823691L;
    4. final void lock() {
    5. //cas操作
    6. if (compareAndSetState(0, 1))
    7. //锁抢占,设置当前线程获得了锁
    8. setExclusiveOwnerThread(Thread.currentThread());
    9. else
    10. acquire(1);
    11. }
    12. protected final boolean tryAcquire(int acquires) {
    13. return nonfairTryAcquire(acquires);
    14. }
    15. }
    1. public final void acquire(int arg) {
    2. if (!tryAcquire(arg) &&//尝试抢占一次,如果失败,继续往下
    3. acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//添加到队列
    4. selfInterrupt();
    5. }
    1. final boolean nonfairTryAcquire(int acquires) {
    2. //再次抢占锁
    3. final Thread current = Thread.currentThread();
    4. int c = getState();
    5. if (c == 0) {
    6. if (compareAndSetState(0, acquires)) {
    7. setExclusiveOwnerThread(current);
    8. return true;
    9. }
    10. }
    11. //当前线程重入,记录重入次数
    12. else if (current == getExclusiveOwnerThread()) {
    13. int nextc = c + acquires;
    14. if (nextc < 0) // overflow
    15. throw new Error("Maximum lock count exceeded");
    16. setState(nextc);
    17. return true;
    18. }
    19. return false;
    20. }
    1. //将当前线程,添加到双向链表
    2. private Node addWaiter(Node mode) {
    3. Node node = new Node(Thread.currentThread(), mode);
    4. Node pred = tail;
    5. if (pred != null) {
    6. node.prev = pred;
    7. if (compareAndSetTail(pred, node)) {
    8. pred.next = node;
    9. return node;
    10. }
    11. }
    12. //队列初始化
    13. enq(node);
    14. return node;
    15. }
    1. final boolean acquireQueued(final Node node, int arg) {
    2. boolean failed = true;
    3. try {
    4. boolean interrupted = false;
    5. for (;;) {
    6. final Node p = node.predecessor();
    7. if (p == head && tryAcquire(arg)) {
    8. setHead(node);
    9. p.next = null; // help GC
    10. failed = false;
    11. return interrupted;
    12. }
    13. if (shouldParkAfterFailedAcquire(p, node) &&//对每个节点的状态进行判断,设置线程的状态
    14. parkAndCheckInterrupt())//LockSupport.park(this);阻塞当前线程
    15. interrupted = true;
    16. }
    17. } finally {
    18. if (failed)
    19. cancelAcquire(node);
    20. }
    21. }

    释放锁逻辑

    1. //Lock.unlock()释放锁
    2. public void unlock() {
    3. sync.release(1);
    4. }
    5. public final boolean release(int arg) {
    6. if (tryRelease(arg)) {
    7. Node h = head;
    8. if (h != null && h.waitStatus != 0)
    9. unparkSuccessor(h);
    10. return true;
    11. }
    12. return false;
    13. }
    14. private void unparkSuccessor(Node node) {
    15. int ws = node.waitStatus;
    16. if (ws < 0)
    17. compareAndSetWaitStatus(node, ws, 0);
    18. Node s = node.next;
    19. if (s == null || s.waitStatus > 0) {
    20. s = null;
    21. for (Node t = tail; t != null && t != node; t = t.prev)
    22. if (t.waitStatus <= 0)
    23. s = t;
    24. }
    25. if (s != null)
    26. LockSupport.unpark(s.thread);
    27. }

    1.cas操作,抢占锁,compareAndSetState(0, 1)
    2.修改成功,标识抢占锁成功,记录当前只有锁的线程
    3.否则
    3.1.尝试重新获取锁,cas操作
    3.2.如果是锁重入,记录重入次数
    3.3.以上都不是返回false
    4.1.如果返回的是false,那么会添加当前线程到队列中