前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JDK源码分析-BlockingQueue

JDK源码分析-BlockingQueue

作者头像
WriteOnRead
发布2019-08-16 17:07:32
2530
发布2019-08-16 17:07:32
举报
文章被收录于专栏:WriteOnRead

概述

BlockingQueue 意为“阻塞队列”,它在 JDK 中是一个接口。

所谓阻塞,简单来说就是当某些条件不满足时,让线程处于等待状态。例如经典的“生产者-消费者”模型,当存放产品的容器满的时候,生产者处于等待状态;而当容器为空的时候,消费者处于等待状态。阻塞队列的概念与该场景类似。

BlockingQueue 的继承关系如下:

可以看到 BlockingQueue 继承自 Queue 接口,它的常用实现类有 ArrayBlockingQueue、LinkedBlockingQueue、DelayQueue 等。同前面一样,本文先分析 BlockingQueue 接口的方法定义,后文再分析其实现类的代码。

PS: 从这个继承体系也可以看出来,直接实现接口的是抽象类,而实现类则通常继承自抽象类。为什么要这样设计呢?因为有些接口的实现类会有多个,而这些类之间有一部分逻辑是相似或者相同的,因此就把这部分逻辑提取到抽象类中,避免代码冗余。

代码分析

BlockingQueue 的方法定义如下:

其方法简单分析如下:

代码语言:javascript
复制
// 将指定元素插入到队列,若成功返回 true,否则抛出异常
boolean add(E e);

// 将指定元素插入到队列,若成功返回 true,否则返回 false
boolean offer(E e);

// 将指定元素插入到队列,若队列已满则等待
void put(E e) throws InterruptedException;

// 将指定元素插入到队列,若成功返回 true,否则返回 false,有超时等待
boolean offer(E e, long timeout, TimeUnit unit)
    throws InterruptedException

// 获取并移除队列的头部,若为空则等待
E take() throws InterruptedException;

// 获取并移除队列的头部,有超时等待(若超时返回 null)
E poll(long timeout, TimeUnit unit)
    throws InterruptedException;

// 返回队列可以接收的容量,若无限制则返回 Integer.MAX_VALUE
int remainingCapacity();

// 删除指定的元素(如果存在),返回是否删除成功
boolean remove(Object o);

// 是否包含指定元素
public boolean contains(Object o);

// 从此队列中删除所有可用元素,并将它们添加到给定集合中
int drainTo(Collection<? super E> c);

// 从此队列中删除所有可用元素,并将它们添加到给定集合中(指定大小)
int drainTo(Collection<? super E> c, int maxElements);

主要方法小结如下:

Throws exceptions

Special value

Blocks

Time out

Insert

add(e)

offer(e)

put(e)

offer(e, time, unit)

Remove

remove()

poll()

take()

poll(time, unit)

Examine

element()

peek()

-

-

Queue 接口前文「JDK源码-Queue, Deque」已进行分析,这里不再赘述。

典型用法

生产者:

代码语言:javascript
复制
class Producer implements Runnable {
    private final BlockingQueue queue;
    Producer(BlockingQueue q) { queue = q; }
    public void run() {
        try {
            // 将产品放入队列
            while (true) { queue.put(produce()); }
        } catch (InterruptedException ex) { ... handle ...}
    }
    Object produce() { ... }
}

消费者:

代码语言:javascript
复制
class Consumer implements Runnable {
    private final BlockingQueue queue;
    Consumer(BlockingQueue q) { queue = q; }
    public void run() {
        try {
            // 从队列中消费产品
            while (true) { consume(queue.take()); }
        } catch (InterruptedException ex) { ... handle ...}
    }
    void consume(Object x) { ... }
}

测试类:

代码语言:javascript
复制
class Setup {
    void main() {
        BlockingQueue q = new SomeQueueImplementation();
        // 创建并启动一个生产者和两个消费者
        Producer p = new Producer(q);
        Consumer c1 = new Consumer(q);
        Consumer c2 = new Consumer(q);
        new Thread(p).start();
        new Thread(c1).start();
        new Thread(c2).start();
    }
}

PS: 上述代码是 BlockingQueue 的文档提供的,仅供参考。

小结

BlockingQueue 是一个接口,它主要定义了阻塞队列的一些方法。阻塞队列在并发编程中使用较多,比如线程池。

相关阅读:

JDK源码-Queue, Deque

Stay hungry, stay foolish.

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WriteOnRead 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档