多线程(3)阻塞队列

目录

 

一、什么是阻塞队列

二、阻塞队列的分类

三、常见的BlockingQueue

四、例子


一、什么是阻塞队列

对于许多线程问题,可以通过使用一个或多个队列以优雅且安全的方式将其形式化。生产者线程向队列插入元素,消费者线程则取出它们。使用队列,可以安全地从一个线程向另一个线程传递数据(不需要考虑同步)。

阻塞队列(Blocking Queue)和非阻塞队列的区别:当试图向队列添加元素而队列已满,或是想从队列移出元素而队列为空的时候,阻塞队列(blocking queue)导致线程阻塞。(他们都是线程安全的,不用考虑线程同步问题)

阻塞队列会自动地平衡负载。如果第一个线程集运行得比第二个慢,第二个线程集在等待结果时会阻塞。如果第一个线程集运行得快,它将等待第二个队列集赶上来。作为使用者,我们无需关心什么时候阻塞线程,什么时候唤醒线程。

二、阻塞队列的分类

阻塞队列方法分为以下3类,这取决于当队列满或空时它们的响应方式。如果将队列当作线程管理工具来使用,将要用到put和take方法。当试图向满的队列中添加或从空的队列中移出元素时,add、remove和element操作抛出异常。当然,在一个多线程程序中,队列会在任何时候空或满,因此,一定要使用offer、poll和peek方法作为替代。这些方法如果不能完成任务,只是给出一个错误提示而不会抛出异常。

方法正常动作特殊情况下的动作
add添加一个元素如果队列满,则抛出IllegalStateException异常
element返回队列的头元素如果队列空,抛出NoSuchElementException异常
remove移出并返回头元素如果队列空,则抛出NoSuchElementException异常
offer添加一个元素并返回true如果队列满,返回false
peek返回队列的头元素如果队列空,则返回null
poll移出并返回队列的头元素如果队列空,则返回null
put添加一个元素如果队列满,则阻塞
take移出并返回头元素如果队列空,则阻塞

ps:poll和peek方法返回空来指示失败。因此,向这些队列中插入null值是非法的;还有带有超时的offer方法和poll方法的变体。

三、常见的BlockingQueue

1、LinkedBlockingQueue

 LinkedBlockingQueue是基于链表实现的一个阻塞队列,默认情况下容量是没有上边界的,但是,也可以选择指定最大容量先进先出

2、ArrayBlockingQueue

ArrayBlockingQueue是基于循环数组实现的一个阻塞队列,在构造时需要指定容量,并且有一个可选的参数来指定是否需要公平性。若设置了公平参数,那么等待了最长时间的线程会优先得到处理。通常,公平性会降低性能,只有在确实非常需要时才使用它。默认非公平,先进先出。有界的数组可以防止资源耗尽问题。

3、PriorityBlockingQueue

PriorityBlockingQueue是基于实现的一个阻塞队列,它是一个带优先级的队列,而不是先进先出队列。元素按照它们的优先级顺序被移出。该队列是没有容量上限,但是,如果队列是空的,取元素的操作会阻塞。

4、SynchronousQuene

            一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。也就是说新任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用线程,则创建新线程,如果线程数量达到maxPoolSize,则执行拒绝策略。

5、DelayQueue

DelayQueue包含实现Delayed接口的对象:

interface Delayed extends Comparable<Delayed> {

    long getDelay(TimeUnit unit);

}

getDelay方法返回对象的残留延迟。负值表示延迟已经结束。元素只有在延迟用完的情况下才能从DelayQueue移除。还必须实现compareTo方法。DelayQueue使用该方法对元素进行排序。

6、TransferQueue

Java SE 7增加了一个TransferQueue接口,允许生产者线程等待,直到消费者准备就绪可以接收一个元素。如果生产者调用

q.transfer(item);

这个调用会阻塞,直到另一个线程将元素(item)删除。LinkedTransferQueue类实现了这个接口。

四、例子

https://blog.csdn.net/qq_33248299/article/details/78869105

 

参考:《Java核心技术 卷I》

            https://blog.csdn.net/yudiandemingzi/article/details/82318390

            https://blog.csdn.net/qq_33248299/article/details/78869105

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值