想必大家都很熟悉生产者-消费者队列,生产者负责添加元素到队列,如果队列已满则会进入阻塞状态直到有消费者拿走元素。相反,消费者负责从队列中拿走元素,如果队列为空则会进入阻塞状态直到有生产者添加元素到队列。BlockingQueue就是这么一个生产者-消费者队列。

BlockingQueue是Queue的子接口

public interface BlockingQueue<E> extends Queue<E>

BlockingQueue拿走元素时,如果队列为空,阻塞等待会有两种情况:

一种是一直等待直到队列不为空,这种情况调用take方法

E take() throws InterruptedException;

另一种就是设定一个超时时间,一直等到超时,这种情况调用的是pool方法

E poll(long timeout, TimeUnit unit) throws InterruptedException;

同样对于添加元素来说,也有两种情况:

一直等待使用put方法

void put(E e) throws InterruptedException;

超时等待使用offer方法

boolean offer(E e, long timeout, TimeUnit unit)
throws InterruptedException;

BlockingQueue的父接口Queue关于拿走元素的接口有两个:remove和pool。

两者的区别在于当队列为空时前者会抛出NoSuchElementException,而后者返回null。

E remove();
E poll();

添加元素的接口也有两个:add和offer。两者的区别在于当队列为满时前者会抛出IllegalStateException,而后者返回false。

boolean add(E e);
boolean offer(E e);

一般来说Queue类型的数据结构会有两种实现:数组和链表。对应到BlockingQueue就是ArrayBlockingQueue和LinkedBlockingQueue,两者都是基于AbstractQueue实现的。

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable

这里很有必要说说AbstractQueue,AbstractQueue只是实现了add和remove方法,而且很有意思的是这两个方法都是借助他们对应的无异常版本的方法offer和pool来实现的。

    public boolean add(E e) {
if (offer(e))
return true;
else
throw new IllegalStateException("Queue full");
}
    public E remove() {
E x = poll();
if (x != null)
return x;
else
throw new NoSuchElementException();
}

这样做的好处无疑是提供了良好的扩展性,也就是把真正添加/拿走元素的实现留给子类来完成(可以实现线程安全和非线程安全两个版本)。

研究BlockingQueue关注的重点就是Blocking是如果实现的,接下来的两篇文章将会详细分析ArrayBlockingQueue和LinkedBlockingQueue如何实现线程的Blocking。

《java.util.concurrent 包源码阅读》05 BlockingQueue的更多相关文章

  1. 《java.util.concurrent 包源码阅读》 结束语

    <java.util.concurrent 包源码阅读>系列文章已经全部写完了.开始的几篇文章是根据自己的读书笔记整理出来的(当时只阅读了部分的源代码),后面的大部分都是一边读源代码,一边 ...

  2. 《java.util.concurrent 包源码阅读》13 线程池系列之ThreadPoolExecutor 第三部分

    这一部分来说说线程池如何进行状态控制,即线程池的开启和关闭. 先来说说线程池的开启,这部分来看ThreadPoolExecutor构造方法: public ThreadPoolExecutor(int ...

  3. 《java.util.concurrent 包源码阅读》02 关于java.util.concurrent.atomic包

    Aomic数据类型有四种类型:AomicBoolean, AomicInteger, AomicLong, 和AomicReferrence(针对Object的)以及它们的数组类型, 还有一个特殊的A ...

  4. 《java.util.concurrent 包源码阅读》04 ConcurrentMap

    Java集合框架中的Map类型的数据结构是非线程安全,在多线程环境中使用时需要手动进行线程同步.因此在java.util.concurrent包中提供了一个线程安全版本的Map类型数据结构:Concu ...

  5. 《java.util.concurrent 包源码阅读》17 信号量 Semaphore

    学过操作系统的朋友都知道信号量,在java.util.concurrent包中也有一个关于信号量的实现:Semaphore. 从代码实现的角度来说,信号量与锁很类似,可以看成是一个有限的共享锁,即只能 ...

  6. 《java.util.concurrent 包源码阅读》06 ArrayBlockingQueue

    对于BlockingQueue的具体实现,主要关注的有两点:线程安全的实现和阻塞操作的实现.所以分析ArrayBlockingQueue也是基于这两点. 对于线程安全来说,所有的添加元素的方法和拿走元 ...

  7. 《java.util.concurrent 包源码阅读》09 线程池系列之介绍篇

    concurrent包中Executor接口的主要类的关系图如下: Executor接口非常单一,就是执行一个Runnable的命令. public interface Executor { void ...

  8. 《java.util.concurrent 包源码阅读》10 线程池系列之AbstractExecutorService

    AbstractExecutorService对ExecutorService的执行任务类型的方法提供了一个默认实现.这些方法包括submit,invokeAny和InvokeAll. 注意的是来自E ...

  9. 《java.util.concurrent 包源码阅读》22 Fork/Join框架的初体验

    JDK7引入了Fork/Join框架,所谓Fork/Join框架,个人解释:Fork分解任务成独立的子任务,用多线程去执行这些子任务,Join合并子任务的结果.这样就能使用多线程的方式来执行一个任务. ...

随机推荐

  1. RT5350 OpenWrt 系统移植jsoncpp

    下载Json包: 下载地址:http://sourceforge.net/projects/jsoncpp/ 如:jsoncpp-src-0.5.0.tar.gz 交叉编译: 1.解压jsoncpp- ...

  2. Kotlin——最详细的数据类型介绍

    任意一种开发语言都有其数据类型,并且数据类型对于一门开发语言来说是最基本的构成,同时也是最基础的语法.当然,kotlin也不例外.kotlin的数据类型和Java是大致相同的,但是他们的写法不同,并且 ...

  3. Linux CentOS7 安装 Mysql5.7.19

    第二次安装会安装失败 1.先停止mysql服务  service mysql stop 2.检查是否卸载干净   find / -name mysql      多用几个命令检查,不要删到其他组件的 ...

  4. LeetCode 245. Shortest Word Distance III (最短单词距离之三) $

    This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...

  5. Java基础笔记9

    super关键字 表示父类对象. 1.可以调用父类中被重写的方法. 2.还有调用父类中的构造方法.放在子类构造方法的第一行. 不能和this关键字同时出现. final关键字 1.修饰属性.表示常量. ...

  6. .9-Vue源码之AST(5)

    上节跑完了超长的parse函数: // Line-9261 function baseCompile(template, options) { // Done! var ast = parse(tem ...

  7. mvc4 实现自己的权限验证 仿Authorize与AllowAnonymous原理

    参考文章 :http://www.cosdiv.com/page/M0/S878/878978.html 实现的效果:在控制器上(Controller)验证权限,在动作(Action)上不验证. 用M ...

  8. sklearn中各算法类的fit,fit_transform和transform函数

    在使用PCA和NFC中有三个函数fit,fit_transform,transform区分不清各自的功能.通过测试,勉强了解各自的不同,在这里做一些笔记. 1.fit_transform是fit和tr ...

  9. Code Lock

    Code Lock Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Su ...

  10. Can you find it?

    Can you find it? Time Limit: 10000/3000 MS (Java/Others) Memory Limit: 32768/10000 K (Java/Others) T ...