美文网首页并发编程
Lock底层原理解析-AQS-双向链表-01

Lock底层原理解析-AQS-双向链表-01

作者: 愤怒的奶牛 | 来源:发表于2020-04-19 22:35 被阅读0次

    1 话题引入-lock 简单使用

    ReentrantLock

    /**
     * j.u.c Lock 接口
     */
    public class LockDemo {
    
        // 重入锁
        private Lock lock = new ReentrantLock();
        private int i = 0;
    
        public void add () {
            try {
                lock.lock();
                i = i+1;
                System.out.println(i);
            }finally {
                lock.unlock();
            }
        }
    
        public static void main(String[] args) {
            LockDemo lockDemo = new LockDemo();
            for (int i = 0; i<10 ; i++) {
                new Thread(()->{
                    lockDemo.add();
                }).start();
            }
        }
    }
    

    入手点 ReentrantLock

    • ReentrantLock 稍微看下jdk 的实现
    * @since 1.5
     * @author Doug Lea
     */
    public class ReentrantLock implements Lock, java.io.Serializable {
        private static final long serialVersionUID = 7373984872572414699L;
        /** Synchronizer providing all implementation mechanics */
        private final Sync sync;
    
        /** 内部类
         * Base of synchronization control for this lock. Subclassed
         * into fair and nonfair versions below. Uses AQS state to
         * represent the number of holds on the lock.
         */
        abstract static class Sync extends AbstractQueuedSynchronizer {
            private static final long serialVersionUID = -5179523762034025860L;
    
            /**
             * Performs {@link Lock#lock}. The main reason for subclassing
             * is to allow fast path for nonfair version.
             */
            abstract void lock();
    
             .............
    /**
         * Sync object for non-fair locks
         */
        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 tryAcquire(int acquires) {
                return nonfairTryAcquire(acquires);
            }
        }
    
    ...............
    
    /**
         * Creates an instance of {@code ReentrantLock}.
         * This is equivalent to using {@code ReentrantLock(false)}.
         */
        public ReentrantLock() { // 默认构造器
            sync = new NonfairSync();
        }
    .......
    

    上面是部分 代码,调用顺序

    1. new ReentrantLock() --> sync = new NonfairSync();
    2. NonfairSync extends Sync ;
    3. Sync extends AbstractQueuedSynchronizer ;
      到这里我们就 看到了 AQS
    • AbstractQueuedSynchronizer

    AbstractQueuedSynchronizer 内部采用了 双向链表来存储 等待执行的线程。分析之前我们先来看一下 java 实现的双向链表:

    • 双向链表
    /**
     * 双向链表
     */
    public class Node {
    
        /**
         * 前一个结点
         */
        private Node pre;
        /**
         * 后一个节点
         */
        private Node next;
        /**
         * 头节点,指向第一个 节点
         */
        private Node header;
        /**
         * 尾节点,指向最后一个节点
         */
        private Node tail;
        /**
         * 节点数据
         */
        private Object data;
    
    
        public Node(Object data) {
            this.data = data;
        }
        public Node() {
        }
    
    
        /**
         * 向链表中添加一个节点,从尾部插入
         * @param newNode
         */
        public void addNode (Node newNode) {
            // 当前 尾部节点
           Node currentTail = this.tail;
           newNode.pre = currentTail;
           currentTail.next = newNode;
           this.tail = newNode;
        }
    
        public void print () {
            Node next = this.header.next;
            while (next != null) {
                System.out.println(next.data.toString());
                next = next.next;
            }
        }
    
        public static void main(String[] args) {
            Node list = new Node();
            Node header = new Node();
            // 初始化 链表, header == tail
            list.header = header;
            list.tail = header;
    
            list.addNode(new Node(1));
            list.addNode(new Node(2));
            list.addNode(new Node(4));
            list.addNode(new Node(3));
            //输出 
            list.print();
    
    
        }
    }
    

    我们温习了一些 双向链表,在分析 AQS 之前,还需要分析一个基础知识 CAS,下一篇文章我们就来学习CAS

    相关文章

      网友评论

        本文标题:Lock底层原理解析-AQS-双向链表-01

        本文链接:https://www.haomeiwen.com/subject/livibhtx.html