美文网首页
BlockingQueue的概述

BlockingQueue的概述

作者: 睦月MTK | 来源:发表于2020-04-23 19:37 被阅读0次

    声明:仅仅对比介绍下BlockingQueue和其各个子接口与实现类


    基接口BlockingQueue<E>
    • 概述

      • BlockingQueue位于java.util.concurrent包下面,是一个为了应对并发情况的队列的接口,其实现类都是线程安全的。
      • 除去集合类提供的批量操作,如addAllcontainsAllretainAllremoveAll,这些方法可以不必是原子性的以外,其他操作都是原子性的。
      • BlockingQueue不接受null元素,如果尝试插入(addputoffernull元素,将会抛出空指针异常。因为在poll方法中,返回null值被认为是操作失败的表现。
      • BlockingQueue可能是有容量限制的,如果没有定义指定的容量,则其容量应为Integer.MAX_VALUE
      • BlockingQueue继承了Collection,所以能够在队列中使用remove这种较为暴力的方法直接去除存在的元素,但是该方法在队列中执行效率很差,只可在特定的场合下使用。
      • BlockingQueue有多种插入(包括入列)、移除(包括出列)、查看的方法,每种方法在操作失败时候的具体行为各不相同,具体见表
      抛出异常 返回false/null 阻塞 带超时的阻塞
      插入 add(e) offer(e) put(e) offer(e, time, unit)
      移除 remove() poll() take() poll(time, unit)
      查看 element() peek() \ \
    • 常见方法

      • add方法,插入一个元素,成功返回true,失败抛出异常

      • offer方法,插入一个元素,成功返回true,失败返回false

      • put方法,插入一个元素,阻塞直到队列中有控件可以操作

      • remove(Object)方法,直接从队列中去除一个指定元素

      • remove方法,去除头部元素并返回该元素,如果队列空则抛出异常

      • poll方法,去除头部元素并返回该元素,如果队列空则返回null

      • take方法,去除头部元素并返回该元素,如果队列为空则阻塞直到队列中有元素

      • element方法,仅仅只返回头部元素,队列为空抛出异常

      • peek方法,仅仅只返回头部元素,队列为空返回null

      • remainingCapacity方法,返回剩余空间数

      • drainTo(Collection)方法,移除所有元素到一个集合中

    • 子接口
      • TransferQueue
        • SynchronnousQueue不同的是,插入时不需要任何等待,直接插入队列,但是会阻塞到直到有一个线程尝试从队列中取出元素

        • 注意,取出的方法必须是take方法或者是带时限的poll方法,因为只有这些方法会在尝试取出元素时进行一定时间的等待,SynchronnousQueue部分也适用这个警告

        • 常见方法:

          • transfer方法,直接插入一个元素进队列,但是会阻塞直到有一个线程尝试从队列中取出这个元素

          • tryTransfer方法,如果没有等待着的消费者,则返回false,且不会插入元素

          • getWaitingConsumerCount

          • hasWaitingConsumer

        • 实现类
          • LinkedTransferQueue
            介绍:略
      • BlockingDeque
        • 并发的双端队列
        • 实现类
          • LinkedBlockingDeque
            介绍:略
    • 实现类
      • ArrayBlockingQueue

        • 由数组支持的BlockingQueue,容量大小是固定的,需要在构造时指定,且不可更改

        • 提供一个可选的“公平政策”标识,如果该标识为false(默认)则队列不会维护都处于等待状态的生产者/消费者的顺序,反之则会维护他们到来的顺序

        • 支持以集合的方式初始化最初的队列

      • LinkedBlockingQueue

        • 由链表支持的BlockingQueue,容量大小可以指定,默认值是Integer.MAX_VALUE,实际大小则是动态的

        • 支持以集合的方式初始化最初的队列

        • 在高并发的情况下的可预测性不如ArrayBlokingQueue

      • PriorityBlockingQueue

        • 按照元素实现的Compareable接口比较而得到的顺序作为队列中元素的排列顺序,所以如果插入的元素不是实现Cpmpareable接口的,将会抛出类型转换异常

        • iterator方法并不会按照该类的顺序规则来遍历,如果想要实现这种效果可以尝试使用Arrays.sort(pbq.toArray)

        • drainTotoArray方法都支持按该类的顺序规则来输出元素

        • 如果两个元素比较相等,则他们的实际排列顺序是不定的

        • 默认初始化容量为11,但是实际容量会不断增加,没有上限,除非资源不足

      • SynchronousQueue

        • 该队列的插入/取出,仅仅只会发生在另一个线程尝试对这个队列进行取出/插入时,所以如果只有一个线程想要插入,那么该线程会阻塞,直到有另一个线程想要取出

        • 由于上诉特性,peekelement方法将没有意义,将会直接返回失败状态,同理的还有size方法、reamingCapacityisEmptytoArraycontainscontainsAlliterator方法等等,因为实际上队列中就是空的

        • 提供一个可选的“公平政策”标识,如果该标识为false(默认)则队列不会维护都处于等待状态的生产/消费者的顺序,反之会维护他们到来的顺序

      • DelayQueue

        • 延迟队列,所有的插入元素必须实现Delayed接口,元素从被插入到队列的那一刻开始便进行倒计时,直到延迟时间结束,该元素才算“真正”显示在队列里

        • 延迟队列的元素排列顺序是按照元素延迟时间结束的早晚来定的,表头元素是整个队列中最早结束延迟的元素

        • 如果在全元素都还在延迟的状态下,尝试取出元素,效果和从空队列取出元素一样

        • 但是毕竟元素是真正在队列中的,调用size方法会返回队列中所有元素的数量,无论是否延迟结束


    额外
    ConcurrentLinkedQueue

    • 也是位于并发包下的一个并发队列,效率比之BlockingQueue要高,前者适用于不太在意元素顺序,高并发的情况,后者适用于保证元素在多线程下的顺序的情况,会有阻塞的情况。
    • 同样不接受null元素
    • 遍历及获取队列长度的结果是不一定准确的
    • addAll, removeAll, retainAll, containsAll, equals, toArray这些方法不是原子的

    参考文档:

    相关文章

      网友评论

          本文标题:BlockingQueue的概述

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