`

读LinkedBlockingDeque源码

阅读更多
//这是一个支持双端操作的可阻塞队列
//先看构造函数
 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) {
	    //说明从集合中读出的元素不能是null
                if (e == null)
                    throw new NullPointerException();
                if (!linkLast(new Node<E>(e)))
                    throw new IllegalStateException("Deque full");
            }
        } finally {
            lock.unlock();
        }
    }


//向队列的队尾
 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();
        return true;
    }

//向头部添加元素如果失败抛出异常
 public void addFirst(E e) {
        if (!offerFirst(e))
            throw new IllegalStateException("Deque full");
    }

//向头部插入非null的元素返回boolean值
 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();
        }
    }


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();
        return true;
    }

public void addLast(E e) {
        if (!offerLast(e))
            throw new IllegalStateException("Deque full");
    }

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();
        }
    }

//在一定时间内尝试插入队首的元素超时返回false。
public boolean offerFirst(E e, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (!linkFirst(node)) {
                if (nanos <= 0)
                    return false;
		 //只有队列已满的情况下才会等待.在非满条件上等待nanos时间。
                nanos = notFull.awaitNanos(nanos);
            }
            return true;
        } finally {
            lock.unlock();
        }
    }

//在一定时间内尝试向队尾插入元素。超时返回false。
  public boolean offerLast(E e, long timeout, TimeUnit unit)
        throws InterruptedException {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (!linkLast(node)) {
                if (nanos <= 0)
                    return false;
                nanos = notFull.awaitNanos(nanos);
            }
            return true;
        } finally {
            lock.unlock();
        }
    }

//可阻塞插入到队列的头部
public void putFirst(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
	   //插入失败后在等待队列变为非满状态然后执行。
            while (!linkFirst(node))
                notFull.await();
        } finally {
            lock.unlock();
        }
    }

//可阻塞的插入到队列的尾部
public void putLast(E e) throws InterruptedException {
        if (e == null) throw new NullPointerException();
        Node<E> node = new Node<E>(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            while (!linkLast(node))
                notFull.await();
        } finally {
            lock.unlock();
        }
    }

//获取队首元素,但不移除,队列为空抛出异常。
public E getFirst() {
        E x = peekFirst();
        if (x == null) throw new NoSuchElementException();
        return x;
    }

public E peekFirst() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return (first == null) ? null : first.item;
        } finally {
            lock.unlock();
        }
    }

public E getLast() {
        E x = peekLast();
        if (x == null) throw new NoSuchElementException();
        return x;
    }

 public E peekLast() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return (last == null) ? null : last.item;
        } finally {
            lock.unlock();
        }
    }

//弹出头元素
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和f.next=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;
    }

//在一定时间内获取头元素超时返回false
 public E pollFirst(long timeout, TimeUnit unit)
        throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            E x;
            while ( (x = unlinkFirst()) == null) {
                if (nanos <= 0)
                    return null;
                nanos = notEmpty.awaitNanos(nanos);
            }
            return x;
        } finally {
            lock.unlock();
        }
    }

//在一定时间内获取尾元素超时返回false
 public E pollLast(long timeout, TimeUnit unit)
        throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            E x;
            while ( (x = unlinkLast()) == null) {
                if (nanos <= 0)
                    return null;
                nanos = notEmpty.awaitNanos(nanos);
            }
            return x;
        } finally {
            lock.unlock();
        }
    }


//可阻塞的获取头元素直到队列非空
public E takeFirst() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            E x;
            while ( (x = unlinkFirst()) == null)
                notEmpty.await();
            return x;
        } finally {
            lock.unlock();
        }
    }

//可阻塞的获取尾元素直到队列非空
public E takeLast() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            E x;
            while ( (x = unlinkLast()) == null)
                notEmpty.await();
            return x;
        } finally {
            lock.unlock();
        }
    }


public E removeFirst() {
        E x = pollFirst();
        if (x == null) throw new NoSuchElementException();
        return x;
    }

 public E removeLast() {
        E x = pollLast();
        if (x == null) throw new NoSuchElementException();
        return x;
    }


public boolean add(E e) {
        addLast(e);
        return true;
    }

public boolean offer(E e) {
        return offerLast(e);
    }

 public void put(E e) throws InterruptedException {
        putLast(e);
    }

   
  public boolean offer(E e, long timeout, TimeUnit unit)
        throws InterruptedException {
        return offerLast(e, timeout, unit);
    }

public E remove() {
        return removeFirst();
    }

 public E poll() {
        return pollFirst();
    }

 public E take() throws InterruptedException {
        return takeFirst();
    }

public E poll(long timeout, TimeUnit unit) throws InterruptedException {
        return pollFirst(timeout, unit);
    }


public E element() {
        return getFirst();
    }

public E peek() {
        return peekFirst();
    }

 public void push(E e) {
        addFirst(e);
    }

    
 public E pop() {
        return removeFirst();
    }


 public E remove() {
        return removeFirst();
    }

//从队首开始搜索删除元素
public boolean removeFirstOccurrence(Object o) {
        if (o == null) return false;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            for (Node<E> p = first; p != null; p = p.next) {
                if (o.equals(p.item)) {
                    unlink(p);
                    return true;
                }
            }
            return false;
        } finally {
            lock.unlock();
        }
    }

void unlink(Node<E> x) {
        // assert lock.isHeldByCurrentThread();
        Node<E> p = x.prev;
        Node<E> n = x.next;
	//如果x是队列的头节点
        if (p == null) {
            unlinkFirst();
	 //如果是尾节点
        } else if (n == null) {
            unlinkLast();
        } else {
            p.next = n;
            n.prev = p;
            x.item = null;
            // Don't mess with x's links.  They may still be in use by
            // an iterator.
            --count;
            notFull.signal();
        }
    }

//从尾部开始循环遍历删除元素
    public boolean removeLastOccurrence(Object o) {
        if (o == null) return false;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            for (Node<E> p = last; p != null; p = p.prev) {
                if (o.equals(p.item)) {
                    unlink(p);
                    return true;
                }
            }
            return false;
        } finally {
            lock.unlock();
        }
    }

//队列的容量
public int remainingCapacity() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return capacity - count;
        } finally {
            lock.unlock();
        }
    }

//将元素弹出到集合中
public int drainTo(Collection<? super E> c) {
        return drainTo(c, Integer.MAX_VALUE);
    }


 public int drainTo(Collection<? super E> c, int maxElements) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            int n = Math.min(maxElements, count);
            for (int i = 0; i < n; i++) {
                c.add(first.item);   // In this order, in case add() throws.
                unlinkFirst();
            }
            return n;
        } finally {
            lock.unlock();
        }
    }
 //清空队列
 public void clear() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            for (Node<E> f = first; f != null; ) {
                f.item = null;
                Node<E> n = f.next;
                f.prev = null;
                f.next = null;
                f = n;
            }
            first = last = null;
            count = 0;
            notFull.signalAll();
        } finally {
            lock.unlock();
        }
    }

//转化为Object数组
public Object[] toArray() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            Object[] a = new Object[count];
            int k = 0;
            for (Node<E> p = first; p != null; p = p.next)
                a[k++] = p.item;
            return a;
        } finally {
            lock.unlock();
        }
    }

//封装到T类型的数组中
public <T> T[] toArray(T[] a) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (a.length < count)
                a = (T[])java.lang.reflect.Array.newInstance
                    (a.getClass().getComponentType(), count);

            int k = 0;
            for (Node<E> p = first; p != null; p = p.next)
                a[k++] = (T)p.item;
            if (a.length > k)
                a[k] = null;
            return a;
        } finally {
            lock.unlock();
        }
    }


/**总结:LinkedBlockingDeque和LinkedBlockingQueue的区别:
    1、LinkedBlockingDeque是双端队列可以在两边插入和删除。而LinkedBlockingQueue基于FIFO顺序的单端队列。
    2、LinkedBlockingDeque的常规方法(add,take)等也是基于FIFO的。所以可以取代LinkedBlockingQueue使用。
    3、虽然可以取代LinkedBlockingQueue,但是建议不要,因为LinkedBlockingQueue是用两把锁实现,
        而LinkedBlockingDeque只用了一把锁效率上LinkedBlockingDeque是不如LinkedBlockingQueue的。
*/


分享到:
评论

相关推荐

    微信小程序 语音跟读 (源码)

    微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟读 (源码)微信小程序 语音跟...

    微信小程序源码 语音跟读(学习版)

    微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码 语音跟读(学习版)微信小程序源码...

    小程序源码 语音跟读 (代码+截图)

    小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 ...

    易语言源码易语言读WAP源码.rar

    易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar 易语言源码易语言读WAP源码.rar

    英语绘本听跟读小程序源码

    【标题】"英语绘本听跟读小程序源码"所涉及的知识点主要集中在移动应用开发、语音识别技术以及教育软件设计上。这个项目是一款专为英语学习者设计的小程序,其核心功能是听读英语绘本,并且能与智能评分系统对接,...

    悦读-uniApp源码.zip

    在这个"悦读-uniApp源码.zip"压缩包中,我们可以推测它包含了一个名为"悦读"的阅读应用的前端源代码。uniApp的项目结构通常包括以下几个主要部分: 1. **main.js**:这是uniApp项目的入口文件,定义了全局配置,如...

    基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)

    基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)基于Python+OpenCV的指针式仪表的识别与读数源码+全部资料(高分项目)...

    易语言源码易语言对象读网页源码.rar

    易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象读网页源码.rar 易语言源码易语言对象...

    易语言源码易语言缓存HTTP读文件源码.rar

    易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar 易语言源码易语言缓存HTTP读文件源码.rar ...

    C#winform读xml源码(适合新手)

    C#winform读xml源码(适合新手)http://www.cnblogs.com/a1656344531/archive/2012/11/28/2792863.html跟着这个教程做的,网址中有不少小错误会让新手比较抓狂,所以附上源码给各位新手,希望你能帮到大家。

    android阅读类的APP“指读”源码.rar

    经过一段时间的Android编程学习后,写了这个比较综合的android阅读类的APP应用,附上了完整的源代码,源代码部分包括了阅读应用APP的源码,以及服务器程序,我给这个阅读小程序起名字叫做“指读”。这里的服务端数据...

    微信小程序源码 语音跟读(源码+截图).rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    易语言源码易语言汇编读字节集源码.rar

    易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码...

    微信小程序——语音跟读(截图+源码).zip

    微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip ...

    易语言源码易语言读HEX文件源码.rar

    易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件...

    易语言源码易语言读网页文件源码.rar

    易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读...

    【微信小程序-毕设期末大作业】语音跟读微信小程序源码.zip

    【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大...

    Python 使用Pandas实现数据库的读、写操作 Python源码

    Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码...

    易语言HTTP读文件模块源码

    资源介绍:。易语言HTTP读文件模块源码例程程序调用系统wininet库的API函数实现HTTP读文件功能。点评:本源码解决了易语言命令HTTP读文件假死的情况。资源作者:。易语言知识库。资源界面:。

Global site tag (gtag.js) - Google Analytics