Java多线程系列--阻塞队列(BlockingQueue)的用法(有实例)

原文网址:Java多线程系列--阻塞队列(BlockingQueue)的用法(有实例)_IT利刃出鞘的博客-CSDN博客

简介

说明

本文用示例介绍Java中阻塞队列(BlockingQueue)的用法。

队列类型

BlockingQueue有这几种类型:ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue、DelayedWorkQueue。

队列类型

说明

ArrayBlockingQueue

        基于数组的FIFO队列;有界;创建时必须指定大小;

        入队和出队共用一个可重入锁。默认使用非公平锁。

LinkedBlockingQueue

        基于链表的FIFO队列;有/无界;默认大小是 Integer.MAX_VALUE(无界),可自定义(有界);

        两个重入锁分别控制元素的入队和出队,用Condition进行线程间的唤醒和等待。

        吞吐量通常要高于ArrayBlockingQueue。

        默认大小的LinkedBlockingQueue将导致所有 corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程不会超过 corePoolSize。(因此,maximumPoolSize 的值也就无效了)。当每个任务相互独时,适合使用无界队列;例如, 在 Web 页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。

SynchronousQueue

        无缓存的等待队列;无界;可认为大小为0。
        不保存提交任务,直接提交出去。若超出corePoolSize个任务,直接创建新线程来执行任务,直到(corePoolSize+新建线程)> maximumPoolSize。

        此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线 程具有增长的可能性。

        吞吐量通常要高于LinkedBlockingQueue。

        //也有地方说:是一个不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态

        详见下边的:CachedThreadPool的execute流程

PriorityBlockingQueue

        基于链表的优先级队列;有/无界;默认大小是 Integer.MAX_VALUE,可自定义;

        类似于LinkedBlockingQueue,但是其所含对象的排序不是FIFO,而是依据对象的自然顺序或者构造函数的Comparator决定。

DelayedWorkQueue

常用方法

放入数据

方法

说明

offer(E e)

向队列尾部插入一个元素。该方法是非阻塞的。

如果队列中有空闲:插入成功后返回 true。

如果队列己满:丢弃当前元素然后返回false。

如果e元素为null:抛出NullPointerException异常。

offer(E o, long timeout, TimeUnit unit)

可以设定等待的时间,若在指定的时间内,还不能往队列中加入BlockingQueue,则返回失败。

add(E e)

内部调用offer方法。

与直接调用offer的区别:

add:失败时,抛出异常

offer:失败时,返回false

put(E e)

向队列尾部插入一个元素。

如果队列中有空闲:插入后直接返回。

如果队列己满:阻塞当前线程,直到队列有空闲插入成功后返回。

如果在阻塞时被其他线程设置了中断标志:被阻塞线程会抛出InterruptedException异常而返回。

如果e元素为null:抛出NullPointerException异常。

获取数据

方法

说明

poll()

获取当前队列头部元素并从队列里面移除它。

如果队列为空则返回null。

poll(long timeout, TimeUnit unit)

从BlockingQueue取出(会删除对象)一个队首的对象。

一旦在指定时间内有数据可取,则立即返回队列中的数据。

若直到时间超时还没有数据可取,返回失败。

take()

获取当前队列头部元素并从队列里面移除它。

如果队列为空则阻塞当前线程直到队列不为空然后返回元素;

如果在阻塞时被其他线程设置了中断标志,则被阻塞线程会抛出InterruptedException异常而返回。

drainTo()

一次性从BlockingQueue获取(会删除对象)所有可用的数据对象(可指定获取数据的个数)。

本方法可提升获取数据效率,不需要多次分批加锁或释放锁。

其他方法

方法

说明

remainingCapacity()

获取队列中剩余的空间

contains(Object o)

判断队列中是否拥有该值。

remove(Object o)

从队列中移除指定的值。

size()

获得队列中有多少值。

(返回AtomicLong的值)

上边是文章的部分内容,为便于维护,全文已迁移到此网址:Java-阻塞队列(BlockingQueue)的用法(有实例) - 自学精灵

  • 31
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT利刃出鞘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值