最近分析sparkstreaming源码时,发现内部block是用ArrayBlockingQueue存储的,特总结一下相关知识。
BlockQueue
顾名思义,阻塞队列,符合典型的生产者-消费者模型:当队列空时,消费者会自动挂起等待;当队列满时,生产者会自动的挂起等待。
队列依据访问方式不同,分为两种:
先进先出(FIFO):事件排队,依次处理。
后进先出(LIFO):处理最新的事件,及时性好,但可能会饥饿。
核心方法
添加数据:
offer(E object):将object放入queue中,成功则返回true,失败返回false。该方法不阻塞,即若queue满,则立即返回false。
offer(E object, long timeout, TimeUnit unit):设置等待时间timeout,在指定的等待时间内添加成功都返回true,否则返回false。
put(E object):将object放入queue中,若queue满,则阻塞等待,直到queue不满时,被唤醒添加数据。
获取数据:
poll(long timeout, TimeUnit unit):设置等待时间timeout,在指定的等待时间内获取数据便返回该object,否则返回null。
take():获取object,若queue为空,则阻塞等待,直到queue中有数据时,被唤醒获取数据。
子类
ArrayBlockingQueue:
由数组组成的有界阻塞队列,符合FIFO,生产者和消费者公用一个锁,所以不是真正的并行。
LinkedBlockingQueue:
由链表组成的可改变大小的阻塞队列,符合FIFO,生产者和消费者各自使用独立的锁,真正的并行。在默认队列大小(Integer.MAX_VALUE)时,消费者速率过快会导致内存耗尽。
DelayQueue:
队列大小没有限制,生产者永远不会阻塞,消费者只有当其指定的延迟时间到了,才能够从队列中获取到该元素,否则会被阻塞。
PriorityBlockingQueue:
类似LinkedBlockingQueue,排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。生产者不会阻塞,消费者会阻塞,生产者过快时,会耗尽内存。
SynchronousQueue:
同步队列。容量可以看成1,每个插入必须等待另一个线程移除,反之亦然。
References: