AQS原理

以非公平锁为例子:

package com.jmdf.redis.project.aqs;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class TestAQS {
    private  static Lock lock = new ReentrantLock();
    public static void main(String[] args) {
        Thread[] threads = new Thread[3];

        for (int i = 0;i<threads.length;i++) {
            threads[i] = new Thread(()->{
                lock.lock(); //①→加锁
                try { Thread.sleep(Integer.MAX_VALUE); }catch(Exception e){ } 
                finally {
                 lock.unlock(); ②→//解锁
                  }
            },"Thread"+i);
        }

        for (Thread thread :threads) thread.start();

        for (Thread thread :threads) try { thread.join(); } catch (InterruptedException e) { e.printStackTrace(); }
    }
}

AQS原理_第1张图片
AQS原理_第2张图片
AQS原理_第3张图片

 /**
         * Performs lock.  Try immediate barge, backing up to normal
         * acquire on failure.
         */
        final void lock() {
            if (compareAndSetState(0, 1)) //unsafe.compareAndSwapInt(this, stateOffset, expect, update);
                setExclusiveOwnerThread(Thread.currentThread()); //当前锁的所有权线程
                //if段操作后面还有,前面重复为了提高性能。
            else
                acquire(1); //获取锁失败→ 
        }
  /**
     * Acquires in exclusive mode, ignoring interrupts.  Implemented
     * by invoking at least once {@link #tryAcquire},
     * returning on success.  Otherwise the thread is queued, possibly
     * repeatedly blocking and unblocking, invoking {@link
     * #tryAcquire} until success.  This method can be used
     * to implement method {@link Lock#lock}.
     *
     * @param arg the acquire argument.  This value is conveyed to
     *        {@link #tryAcquire} but is otherwise uninterpreted and
     *        can represent anything you like.
     */
    public final void acquire(int arg) {
        if (!tryAcquire(arg) && //①→尝试获取锁
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg))//addWaiter(Node.EXCLUSIVE)尝试获取锁失败,自旋CAS加入CHL队列,acquireQueued 方法 自旋尝试获取锁
            selfInterrupt(); //中断
    }

    protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

 /**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         * 非公平锁实现
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread(); //当前线程,局部变量在虚拟机栈里
            int c = getState();  //volatile修饰的int变量
            if (c == 0) {  //前面的线程获取锁,完成业务后,占用的锁释放了
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) { //state !=0,当前线程等于Lock实现类锁所有权线程,则为可重入锁,不需要获取锁,只需要state++;
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false; //当前线程尝试获取锁失败。
        }




  /**
         * Fair version of tryAcquire.  Don't grant access unless
         * recursive call or no waiters or is first.
         * 公平锁实现
         */
        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;
        }



  / *          if there is a queued thread preceding the
     *         current thread, and {@code false} if the current thread
     *         is at the head of the queue or the queue is empty
     *         @since 1.7
     *         公平锁判断队列为空才去尝试获取锁,高并发情况下并非绝对公平
     */
    public final boolean hasQueuedPredecessors() {
        // The correctness of this depends on head being initialized
        // before tail and on head.next being accurate if the current
        // thread is first in queue.
        Node t = tail; // Read fields in reverse initialization order  尾节点
        Node h = head;   //头节点
        Node s;
        return h != t &&  //h!=t  为false==→空队列,后面判断是为了防止并发
            ((s = h.next) == null || s.thread != Thread.currentThread());
    }

private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        // Try the fast path of enq; backup to full enq on failure
        Node pred = tail;
        if (pred != null) {
            node.prev = pred;
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        enq(node);
        return node;
    }



  private Node enq(final Node node) {
        for (;;) {
            Node t = tail;
            if (t == null) { // Must initialize
                if (compareAndSetHead(new Node())) //延迟初始化队列节点 在AQ类加载时声明了成员节点,static{}获取了head、tail、pre、next在jvm里的位置的偏移量,为以后cas做准备
                    tail = head; //头尾节点相等,队列初始化结束,队列为空
            } else {
                node.prev = t;   //    tail ←prev  node
                if (compareAndSetTail(t, node)) {//若队列不为空,尾节点指针指向当前节点的前置节点,cas 把当前node.next =null 尾节点cas成功!             node  next→null
                    t.next = node;          //            tail next→node
                    return t;          
                }
            }
        }
    }
 /**
     * Acquires in exclusive uninterruptible mode for thread already in
     * queue. Used by condition wait methods as well as acquire.
     *
     * @param node the node
     * @param arg the acquire argument
     * @return {@code true} if interrupted while waiting
     */
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();//node 节点的前置节点
                if (p == head && tryAcquire(arg)) {  //如果前置节点为head ,则可以尝试获取锁
                    setHead(node);      //把该节点设置为head节点
                    p.next = null; // help GC   释放 node节点的前置节点,从队列中清除
                    failed = false;
                    return interrupted; //false
                }
                if (shouldParkAfterFailedAcquire(p, node) &&  
                    parkAndCheckInterrupt())
                    interrupted = true;
            }
        } finally {
            if (failed)
                cancelAcquire(node);
        }
    }



  private void setHead(Node node) {
        head = node;
        node.thread = null;
        node.prev = null;
    }








你可能感兴趣的:(JUC多线程及高并发)