美文网首页Java0.面试技能系列
(十三)J.U.C-BlockingQueue

(十三)J.U.C-BlockingQueue

作者: 匆匆岁月 | 来源:发表于2018-08-16 10:51 被阅读7次

BlockingQueue阻塞队列

主要应用场景:生产者消费者模型,是线程安全的

阻塞情况:

1、当队列满了进行入队操作
2、当队列空了的时候进行出队列操作

四套方法:

BlockingQueue提供了四套方法,分别来进行插入、移除、检查。每套方法在不能立刻执行时都有不同的反应。


  • Throws Exceptions :如果不能立即执行就抛出异常。
  • Special Value:如果不能立即执行就返回一个特殊的值。
  • Blocks:如果不能立即执行就阻塞
  • Times Out:如果不能立即执行就阻塞一段时间,如果过了设定时间还没有被执行,则返回一个值

实现类:

  • ArrayBlockingQueue:它是一个有界的阻塞队列,内部实现是数组,初始化时指定容量大小,一旦指定大小就不能再变。采用FIFO方式存储元素。

  • DelayQueue:阻塞内部元素,内部元素必须实现Delayed接口,Delayed接口又继承了Comparable接口,原因在于DelayQueue内部元素需要排序,一般情况按过期时间优先级排序。

public interface Delayed extends Comparable<Delayed> {
    long getDelay(TimeUnit unit);
}

DalayQueue内部采用PriorityQueue与ReentrantLock实现。

public class DelayQueue<E extends Delayed> extends AbstractQueue<E>
    implements BlockingQueue<E> {

    private final transient ReentrantLock lock = new ReentrantLock();
    private final PriorityQueue<E> q = new PriorityQueue<E>();
    ...
}
  • LinkedBlockingQueue:大小配置可选,如果初始化时指定了大小,那么它就是有边界的。不指定就无边界(最大整型值)。内部实现是链表,采用FIFO形式保存数据。
public LinkedBlockingQueue() {
    this(Integer.MAX_VALUE);//不指定大小,无边界采用默认值,最大整型值
}
  • PriorityBlockingQueue:带优先级的阻塞队列。无边界队列,允许插入null。插入的对象必须实现Comparator接口,队列优先级的排序规则就是按照我们对Comparable接口的实现来指定的。我们可以从PriorityBlockingQueue中获取一个迭代器,但这个迭代器并不保证能按照优先级的顺序进行迭代。
public boolean add(E e) {//添加方法
    return offer(e);
}
public boolean offer(E e) {
    if (e == null)
        throw new NullPointerException();
    final ReentrantLock lock = this.lock;
    lock.lock();
    int n, cap;
    Object[] array;
    while ((n = size) >= (cap = (array = queue).length))
        tryGrow(array, cap);
    try {
        Comparator<? super E> cmp = comparator;//必须实现Comparator接口
        if (cmp == null)
            siftUpComparable(n, e, array);
        else
            siftUpUsingComparator(n, e, array, cmp);
        size = n + 1;
        notEmpty.signal();
    } finally {
        lock.unlock();
    }
    return true;
}
  • SynchronusQueue:只能插入一个元素,同步队列,无界非缓存队列,不存储元素。

作为BlockingQueue中的一员,SynchronousQueue与其他BlockingQueue有着不同特性:

  1. SynchronousQueue没有容量。与其他BlockingQueue不同,SynchronousQueue是一个不存储元素的BlockingQueue。每一个put操作必须要等待一个take操作,否则不能继续添加元素,反之亦然。
  2. 因为没有容量,所以对应 peek, contains, clear, isEmpty … 等方法其实是无效的。例如clear是不执行任何操作的,contains始终返回false,peek始终返回null。
  3. SynchronousQueue分为公平和非公平,默认情况下采用非公平性访问策略,当然也可以通过构造函数来设置为公平性访问策略(为true即可)。
  4. 若使用 TransferQueue, 则队列中永远会存在一个 dummy node(这点后面详细阐述)。

SynchronousQueue非常适合做交换工作,生产者的线程和消费者的线程同步以传递某些信息、事件或者任务。

相关文章

  • (十三)J.U.C-BlockingQueue

    BlockingQueue阻塞队列 主要应用场景:生产者消费者模型,是线程安全的 阻塞情况: 1、当队列满了进行入...

  • J.U.C-BlockingQueue

    在某些情况下,对阻塞队列的访问可能会造成阻塞: 当队列满的时候进行入队操作 当队列空的时候进行出队操作阻塞队列是线...

  • 十三

    我们住在十三 很多故事与之相关…… 学号用过十三 那天是十三 昨天也是十三 心中的内设刚好, 还是十三…… 我算过...

  • 后来

    高中入学成绩学校第五十三 班级人数五十三 我五号她十三 我笔画二十三画加她三十为五十三 高考排号尾数五十三 体重公...

  • 大学法撒、 三到四三十三岁三十三岁三十三岁三十三岁的 大叔

  • 2021-03-16

    一个人三岁可以可爱,十三岁也可以可爱,二十三岁也可以可爱,四十三也可以可爱,哪怕七十三、八十三、九十三豆可以很可爱...

  • 学习中医

    那就非《医学十三经》莫属。儒家有“十三经”,佛门有“释氏十三经”,中医也有“医学十三经”之说。一共是是十三本书。 ...

  • 21/4 我读《悖论13》

    三月十三日,星期五十三时十三分十三秒,最后十三个人。 这是印在封面上的几个字,也是故事的开端。 ...

  • 我们最终把彼此弄丢了

    第十三更 今天是来简书的第十三天。 十三,十三,十三,一个太熟悉的数字。 失散,失散,失散,我们最终把彼此弄丢了。...

  • 闲篇 | 十三巟

    十三,在中国是个高级的数。 十三在儒释道三教中皆是大吉利数。佛教传来我国分为十三宗,布达拉宫十三层,天宁寺佛塔十三...

网友评论

    本文标题:(十三)J.U.C-BlockingQueue

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