(转自:https://blog.csdn.net/wei_ya_wen/article/details/19344939 侵删)

在java多线程操作中, BlockingQueue<E> 常用的一种方法之一。在看jdk内部尤其是一些多线程,大量使用了blockinkQueue 来做的。

借用jdk api解释下:

BlockingQueue 方法以四种形式出现,对于不能立即满足但可能在将来某一时刻可以满足的操作,这四种形式的处理方式不同:第一种是抛出一个异常,第二种是返回一个特殊值(null 或 false,具体取决于操作),第三种是在操作可以成功前,无限期地阻塞当前线程,第四种是在放弃前只在给定的最大时间限制内阻塞。下表中总结了这些方法:

  抛出异常 特殊值 阻塞 超时
插入 add(e) offer(e) put(e) offer(e, time, unit)
移除 remove() poll() take() poll(time, unit)
检查 element() peek() 不可用 不可用

offer: 将指定元素插入此队列中(如果立即可行且不会违反容量限制),成功时返回 true,如果当前没有可用的空间,则返回 false,不会抛异常:

java源代码

[html] view plain copy
  1. public boolean offer(E e) {
  2. if (e == null) throw new NullPointerException();
  3. final ReentrantLock lock = this.lock;
  4. lock.lock();
  5. try {
  6. if (count == items.length)
  7. return false;
  8. else {
  9. insert(e);
  10. return true;
  11. }
  12. } finally {
  13. lock.unlock();
  14. }
  15. }

put:

将指定元素插入此队列中,将等待可用的空间.通俗点说就是>maxSize 时候,阻塞,直到能够有空间插入元素

java源代码:

[html] view plain copy
  1. public void put(E e) throws InterruptedException {
  2. if (e == null) throw new NullPointerException();
  3. final E[] items = this.items;
  4. final ReentrantLock lock = this.lock;
  5. lock.lockInterruptibly();
  6. try {
  7. try {
  8. while (count == items.length)
  9. notFull.await();
  10. } catch (InterruptedException ie) {
  11. notFull.signal(); // propagate to non-interrupted thread
  12. throw ie;
  13. }
  14. insert(e);
  15. } finally {
  16. lock.unlock();
  17. }
  18. }

take: 获取并移除此队列的头部,在元素变得可用之前一直等待 。queue的长度 == 0 的时候,一直阻塞

java 源代码:

[html] view plain copy
  1. public E take() throws InterruptedException {
  2. final ReentrantLock lock = this.lock;
  3. lock.lockInterruptibly();
  4. try {
  5. try {
  6. while (count == 0)
  7. notEmpty.await();
  8. } catch (InterruptedException ie) {
  9. notEmpty.signal(); // propagate to non-interrupted thread
  10. throw ie;
  11. }
  12. E x = extract();
  13. return x;
  14. } finally {
  15. lock.unlock();
  16. }
  17. }

add: 和collection的add一样,没什么可以说的。如果当前没有可用的空间,则抛出 IllegalStateException



例子如下:

[html] view plain copy
  1. public static void main(String[] args) {
  2. java.util.concurrent.Executor executor = Executors.newFixedThreadPool(10);
  3. Runnable task = new Runnable() {
  4. @Override
  5. public void run() {
  6. System.out.println("ggg");
  7. }
  8. };
  9. executor.execute(task);
  10. */
  11. BlockingQueue q = new ArrayBlockingQueue(10);
  12. Producer p = new Producer(q);
  13. Consumer c1 = new Consumer(q);
  14. Consumer c2 = new Consumer(q);
  15. new Thread(p).start();
  16. new Thread(c1).start();
  17. new Thread(c2).start();
  18. }
  19. }
  20. class Producer implements Runnable {
  21. private final BlockingQueue<Object> queue;
  22. Producer(BlockingQueue q) { queue = q; }
  23. public void run() {
  24. for(int i=0;i<100;i++){
  25. try {
  26. queue.put(i);
  27. } catch (InterruptedException e1) {
  28. // TODO Auto-generated catch block
  29. e1.printStackTrace();
  30. }
  31. try {
  32. Thread.sleep(20);
  33. } catch (InterruptedException e) {
  34. // TODO Auto-generated catch block
  35. e.printStackTrace();
  36. }
  37. }
  38. }
  39. }
  40. class Consumer implements Runnable {
  41. private final BlockingQueue queue;
  42. Consumer(BlockingQueue q) { queue = q; }
  43. public void run() {
  44. try {
  45. while(true) {
  46. consume(
  47. queue.take()
  48. );
  49. }
  50. } catch (InterruptedException ex) {
  51. }
  52. }
  53. void consume(Object x) {
  54. System.out.println(x);
  55. }
  56. }

BlockingQueue中 take、offer、put、add的一些比较的更多相关文章

  1. 多线程之BlockingQueue中 take、offer、put、add的一些比较

    一.概述: BlockingQueue作为线程容器,可以为线程同步提供有力的保障.   二.BlockingQueue定义的常用方法 1.BlockingQueue定义的常用方法如下:   抛出异常 ...

  2. Dockerfile 中的 COPY 与 ADD 命令

    Dockerfile 中提供了两个非常相似的命令 COPY 和 ADD,本文尝试解释这两个命令的基本功能,以及其异同点,然后总结其各自适合的应用场景. Build 上下文的概念 在使用 docker ...

  3. 【Docker】涨姿势,深入了解Dockerfile 中的 COPY 与 ADD 命令

    参考资料:https://www.cnblogs.com/sparkdev/p/9573248.html Dockerfile 中提供了两个非常相似的命令 COPY 和 ADD,本文尝试解释这两个命令 ...

  4. 【转载】C#中ArrayList集合类使用Add方法添加元素

    ArrayList集合是C#中的一个非泛型的集合类,是弱数据类型的集合类,可以使用ArrayList集合变量来存储集合元素信息,任何数据类型的变量都可加入到同一个ArrayList集合中,因此使用Ar ...

  5. docker(11)Dockerfile 中的COPY与ADD 命令

    前言 Dockerfile 中提供了两个非常相似的命令 COPY 和 ADD,本文尝试解释这两个命令的基本功能,以及其异同点,然后总结其各自适合的应用场景. Build 上下文的概念 在使用 dock ...

  6. java源码研究--List中的set和add方法区别

    在处理一道题目是,发现他们使用了List 中的set 方法,这个方法我平时很少用到,今天来研究一下,set和add的区别 add(int index,Object obj)方法与set(int ind ...

  7. oracle11.2中分区功能测试之add&amp;split partition对global&amp;local index的影响

    生产库中某些大表的分区异常,需要对现有表进行在线操作,以添加丢失分区,因为是生产库,还是谨慎点好,今天有空,针对add&split分区对global&local索引的影响进行了测试,测 ...

  8. 记录 Java 的 BlockingQueue 中的一些坑

    最近学习了 BlockingQueue,发现 java 的 BlockingQueue 并不是每一个实现都按照 BlockingQueue 的语意来的,其中有不少坑. 直接上代码吧: 1.关于Prio ...

  9. [学习笔记] 在Eclipse中添加用户库 Add User Libraries ,在项目中引用用户库

    如果还没有安装Eclipse, 则请参考前文:  [学习笔记] 下载.安装.启动 Eclipse(OEPE) 添加用户库 本文主要介绍在项目中直接使用第三方库的情况.就是把第三方的jar文件直接放到某 ...

随机推荐

  1. pytest文档46-关于https请求警告问题(InsecureRequestWarning: Unverified HTTPS request is being made)

    前言 使用 pytest 执行 https 请求用例的时候,控制台会出现警告:InsecureRequestWarning: Unverified HTTPS request is being mad ...

  2. Spring mvc文件上传实现

    Spring mvc文件上传实现 jsp页面客户端表单编写 三个要素: 1.表单项type="file" 2.表单的提交方式:post 3.表单的enctype属性是多部分表单形式 ...

  3. spring boot:spring security+oauth2+sso+jwt实现单点登录(spring boot 2.3.3)

    一,sso的用途 ? 1,如果有多个应用系统,用户只需要登录一次就可以访问所有相互信任的应用系统. 不需要每次输入用户名称和用户密码, 也不需要创建并记忆多套用户名称和用户密码. 2,系统管理员只需维 ...

  4. linux 压缩命令 zip

    1.zip命令 例如:zip -r mysql.zip mysql 该句命令的含义是:将mysql文件夹压缩成mysql.zip zip -r abcdef.zip abc def.txt 这句命令的 ...

  5. 使用PyPdf2合并PDF文件(没有空白、报错)

    使用PyPdf2合并PDF文件(没有空白.报错) 对于合并之后pdf空白,或者出现 'latin-1' codec can't encode characters in position 8-11: ...

  6. APP打开(二)—标准流程

    APP打开是一个老生常谈的话题,在互联网时代,在APP遍地的时代,APP打开是每一个APP的必经之路,今天我想通过以下几点来阐述APP打开的标准流程,给这个话题写一点自己的见解. APP打开现状 标准 ...

  7. .gdbinit文件配置

    .gdbinit文件配置 #打印数组的索引下标 set print array-indexes on #每行打印一个结构体成员 set print pretty on #除了断点有关的线程会被停下来, ...

  8. 解放开发者!3款工具实现快速K8S开发

    本文转自Rancher Labs 关注我们,即可第一时间获取K8S教程哦 简 介 时至今日,Kubernetes正在变得越来越重要,不仅仅是运维需要Kubernetes,在开发的世界里Kubernet ...

  9. 抽空学学KVM(七):虚拟机快照和克隆

    前几天学写了KVM中qume-info命令的使用,今天学学在虚拟化里面用处广泛的快照和克隆功能,snapshot和virt-clone.对于snapshot命令的使用其实很简单.进入virsh界面以后 ...

  10. Vue.js 学习笔记之六:构建更复杂的组件

    在掌握了如何构建与编译 Vue 组件的基础知识之后,接下来就可以试着来构建一些更具有实际用处的复杂组件了.为了赋予组件更具实用性的后面,首先要做的就是让这些组件具备监听用户自定义事件的能力,并且允许用 ...