zoukankan      html  css  js  c++  java
  • 源码分析之Queue(一)Queue & Deque & BlockingQueue

    Queue源码解析

      Queue是Java集合框架中的一员,继承于Collection接口。与List、Set相同的是,Queue也实现了一种数据结构,这就是队列。队列是计算机中的一种数据结构,保存在其中的数据具有“先进先出(FIFO,First In First Out)”的特性。

    public interface Queue<E> extends Collection<E> {
        /**
         * Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions
         * 将元素插入队列*/
        boolean add(E e);
    
        /**
         * Inserts the specified element into this queue if it is possible to do so immediately without violating capacity restrictions.
         * 将元素插入队列,与add相比,在容量受限时应使用这个*/
        boolean offer(E e);
    
        /**
         * Retrieves and removes the head of this queue.  This method differs from {@link #poll poll} only in that it throws an exception if this queue is empty.
         * 将队首的元素删除,当队列为空时,则抛出异常
    */
        E remove();
    
        /**
         * Retrieves and removes the head of this queue,or returns {@code null} if this queue is empty.
         * 将对首的元素删除,当队列为空时,则返回null
         * @return the head of this queue, or {@code null} if this queue is empty
         */
        E poll();
    
        /**
         * Retrieves, but does not remove, the head of this queue.  This method differs from {@link #peek peek} only in that it throws an exception if this queue is empty.     * 获取队首元素但不移除,当队列为空时,则抛出异常
         * @return the head of this queue
         * @throws NoSuchElementException if this queue is empty
         */
        E element();
    
        /**
         * Retrieves, but does not remove, the head of this queue,or returns {@code null} if this queue is empty.   * 获取队首元素但不移除,当队列为空时,则返回Null
         * @return the head of this queue, or {@code null} if this queue is empty
         */
        E peek();
    }
    View Code

    Deque源码解决 

      Deque全称为double ended queue,即双向队列,它允许在两侧插入或删除元素,同时也建议我们不要向其中插入null值。除此之外,其余特性则和父级Queue类似。Deque中定义的方法主要分为四部分,第一部分就如Deque定义所言,提供两侧插入或删除的方法。第二部分是继承自Queue的实现。第三部分表示如果要基于此实现一个Stack,需要实现的方法。最后一部分是继承自Collection的方法。

    public interface Deque<E> extends Queue<E> {
      //针对两侧操作
       //在队首添加元素
       void addFirst(E e);
       //在队首添加元素
       boolean offerFirst(E e);
       //在队尾添加元素
       void addLast(E e);
       boolean offerLast(E e);
       //删除队首元素
       E removeFirst();
       E pollFirst();
       //删除队尾元素
       E removeLast();
       E pollLast();
       //获取队首元素
       E getFirst();
       E peekFirst();
       //获取队尾元素
       E getLast();
       E peekLast();
       //删除第一个事件,大多数指的是删除第一个和 o equals的元素
       boolean removeFirstOccurrence(Object o);
       //删除最后一个事件,大多数指的是删除最后一个和 o equals的元素
       boolean removeLastOccurrence(Object o);
    
       //实现Stack  Stack仅在一侧支持插入删除操作等操作,遵循LIFO原则。
       //与addFirst()等价
       void push(E e);
       //与removeFirst()等价
       E pop();
    }
    View Code

    BlockingQueue源码解析

      在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利。

    public interface BlockingQueue<E> extends Queue<E> {
    
        //将给定的元素设置到队列中,如果设置成功返回true, 否则抛出异常。如果是往限定了长度的队列中设置值,推荐使用offer()方法。
        boolean add(E e);
    
        //将给定的元素设置到队列中,如果设置成功返回true, 否则返回false. e的值不能为空,否则抛出空指针异常。
        boolean offer(E e);
    
        //将元素设置到队列中,如果队列中没有多余的空间,该方法会一直阻塞,直到队列中有多余的空间。
        void put(E e) throws InterruptedException;
    
        //将给定元素在给定的时间内设置到队列中,如果设置成功返回true, 否则返回false.
        boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;
    
        //从队列中获取值,如果队列中没有值,线程会一直阻塞,直到队列中有值,并且该方法取得了该值。
        E take() throws InterruptedException;
    
        //在给定的时间里,从队列中获取值,时间到了直接调用普通的poll方法,为null则直接返回null。
        E poll(long timeout, TimeUnit unit) throws InterruptedException;
    
        //获取队列中剩余的空间。
        int remainingCapacity();
    
        //从队列中移除指定的值。
        boolean remove(Object o);
    
        //判断队列中是否拥有该值。
        public boolean contains(Object o);
    
        //将队列中值,全部移除,并发设置到给定的集合中。
        int drainTo(Collection<? super E> c);
    
        //指定最多数量限制将队列中值,全部移除,并发设置到给定的集合中。
        int drainTo(Collection<? super E> c, int maxElements);
    }
    View Code

    方法分类:

      抛出异常 特殊值 阻塞 超时
    插入 add(e) offer(e) put(e) offer(e, time, unit)
    移除 remove() poll() take() poll(time, unit)
    取值 element() peek() 不可用 不可用

    阻塞队列成员:

    队列有界性数据结构
    ArrayBlockingQueue bounded(有界) 加锁 arrayList
    LinkedBlockingQueue optionally-bounded 加锁 linkedList
    PriorityBlockingQueue unbounded 加锁 heap
    DelayQueue unbounded 加锁 heap
    SynchronousQueue bounded 加锁
    LinkedTransferQueue unbounded 加锁 heap
    LinkedBlockingDeque unbounded 无锁 heap
    • ArrayBlockingQueue:是一个用数组实现的线程安全的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。【注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁】
    • LinkedBlockingQueue:一个由链表结构组成的有界队列,此队列的长度为Integer.MAX_VALUE。此队列按照先进先出的顺序进行排序。
    • PriorityBlockingQueue: 一个支持线程优先级排序的无界队列,默认自然序进行排序,也可以自定义实现compareTo()方法来指定元素排序规则,不能保证同优先级元素的顺序
    • DelayQueue: 一个实现PriorityBlockingQueue实现延迟获取的无界队列,在创建元素时,可以指定多久才能从队列中获取当前元素。只有延时期满后才能从队列中获取元素。(DelayQueue可以运用在以下应用场景:1.缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。2.定时任务调度。使用DelayQueue保存当天将会执行的任务和执行时间,一旦从DelayQueue中获取到任务就开始执行,从比如TimerQueue就是使用DelayQueue实现的。)
    • SynchronousQueue: 一个不存储元素的阻塞队列,每一个put操作必须等待take操作,否则不能添加元素。支持公平锁和非公平锁。SynchronousQueue的一个使用场景是在线程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。
    • LinkedTransferQueue: 一个由链表结构组成的无界阻塞队列,相当于其它队列,LinkedTransferQueue队列多了transfer和tryTransfer方法。
    • LinkedBlockingDeque: 一个由链表结构组成的双向阻塞队列。队列头部和尾部都可以添加和移除元素,多线程并发时,可以将锁的竞争最多降到一半。
  • 相关阅读:
    CentOS 6.x Radius
    Linux系统优化
    Linux 常用检测命令
    Linux 修改终端命令提示符颜色
    Linux LVM简明教程
    剑指Offer 通过中序和先序遍历重建二叉树
    剑指Offer 树的子结构
    剑指Offer 从上往下打印二叉树(dfs)
    剑指Offer 把字符串转换成整数
    剑指Offer 两个链表的第一个公共结点
  • 原文地址:https://www.cnblogs.com/ryjJava/p/14324257.html
Copyright © 2011-2022 走看看