JUC-LinkedBlockingDeque

一、简介

 1.LinkedBlockingDeque是基于双向链表实现的并发阻塞队列。支持FIFO和FILO两种操作方式。

 2.LinkedBlockingDeque继承了AbstractQueue,实现BlockingDeque接口。也就是支持多线程并发。

二、 属性

    //链表的头结点
    transient Node<E> first;
    //链表的尾节点
    transient Node<E> last;
    //链表的实际元素个数
    private transient int count;
    //链表的最大容量个数
    private final int capacity;
    //线程锁
    final ReentrantLock lock = new ReentrantLock();
    //队列链表为空时,阻塞tabke的队列条件。
    private final Condition notEmpty = lock.newCondition();
    //队列链表满了是,阻塞put的队列。
    private final Condition notFull = lock.newCondition();


三、构造函数

    //默认的初始化大小
    public LinkedBlockingDeque() {
        this(Integer.MAX_VALUE);
    }

    public LinkedBlockingDeque(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
    }

    public LinkedBlockingDeque(Collection<? extends E> c) {
        this(Integer.MAX_VALUE);
        final ReentrantLock lock = this.lock;
        lock.lock(); // Never contended, but necessary for visibility
        try {
            for (E e : c) {
                if (e == null)
                    throw new NullPointerException();
                if (!linkLast(new Node<E>(e)))
                    throw new IllegalStateException("Deque full");
            }
        } finally {
            lock.unlock();
        }
    }

1.offerFirst/offerLast 与 putFirst/putLast区别 队列满了的情况一个前者return false,后者调用notFull.await()

  //在首节点位置添加
 public boolean offerFirst(E e) {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return linkFirst(node);
        } finally {
            lock.unlock();
        }
    }
    //获取首节点,将添加元素E的next指针指向首节点。再把元素E作为首节点。 如果尾节点是null,那么E也是尾节点。不是null的话将E的pre指针指向last节点
    private boolean linkFirst(Node<E> node) {
        // assert lock.isHeldByCurrentThread();
        if (count >= capacity) //判断当先链表的数目大小
            return false;
        Node<E> f = first;
        node.next = f;
        first = node;
        if (last == null)
            last = node;
        else
            f.prev = node;
        ++count;
        notEmpty.signal(); //唤醒notEmpty等待的线程
        return true;
    }


  //添加至尾节点
  public boolean offerLast(E e) {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return linkLast(node);
        } finally {
            lock.unlock();
        }
    }
 
  //将节点E作为尾节点,E.prev并指向原先的尾节点l。判断首节点为null,E也是首节点。不为null,l.next指向E
  private boolean linkLast(Node<E> node) {
        // assert lock.isHeldByCurrentThread();
        if (count >= capacity)
            return false;
        Node<E> l = last;
        node.prev = l;
        last = node;
        if (first == null)
            first = node;
        else
            l.next = node;
        ++count;
        notEmpty.signal(); //唤醒notEmpty等待的线程
        return true;
    }

  //移出首节点元素
   public E pollFirst() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return unlinkFirst();
        } finally {
            lock.unlock();
        }
    }
    private E unlinkFirst() {
        // assert lock.isHeldByCurrentThread();
        Node<E> f = first;
        if (f == null)
            return null;
        Node<E> n = f.next; 
        E item = f.item;
        f.item = null;
        f.next = f; // help GC
        first = n;
        if (n == null)
            last = null;
        else
            n.prev = null;
        --count;
        notFull.signal();
        return item;
    }


    public E pollLast() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return unlinkLast();
        } finally {
            lock.unlock();
        }
    }

    private E unlinkLast() {
        // assert lock.isHeldByCurrentThread();
        Node<E> l = last;
        if (l == null)
            return null;
        Node<E> p = l.prev;
        E item = l.item;
        l.item = null;
        l.prev = l; // help GC
        last = p;
        if (p == null)
            first = null;
        else
            p.next = null;
        --count;
        notFull.signal();
        return item;
    }

猜你喜欢

转载自blog.csdn.net/qq_28126793/article/details/80006416
JUC