阻塞队列:线程安全

按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素。链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。

注意:

1、必须要使用take()方法在获取的时候达成阻塞结果
2、使用poll()方法将产生非阻塞效果

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class BlockingDeque {
//阻塞队列,FIFO
private static LinkedBlockingQueue<Integer> concurrentLinkedQueue = new LinkedBlockingQueue<Integer>();

public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2);

 executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer1</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer2</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer3</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer1</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer2</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer3</span><span style="color:#800000;">"</span><span style="color:#000000;">));

}

static class Producer implements Runnable {
private String name;

 </span><span style="color:#0000ff;">public</span><span style="color:#000000;"> Producer(String name) {  </span><span style="color:#0000ff;">this</span>.name =<span style="color:#000000;"> name;  }  </span><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> run() {  </span><span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = <span style="color:#800080;">1</span>; i &lt; <span style="color:#800080;">10</span>; ++<span style="color:#000000;">i) {  System.</span><span style="color:#0000ff;">out</span>.println(name+ <span style="color:#800000;">"</span><span style="color:#800000;">  生产: </span><span style="color:#800000;">"</span> +<span style="color:#000000;"> i);  </span><span style="color:#008000;">//</span><span style="color:#008000;">concurrentLinkedQueue.add(i);  </span><span style="color:#0000ff;">try</span><span style="color:#000000;"> {concurrentLinkedQueue.put(i);Thread.sleep(</span><span style="color:#800080;">200</span>); <span style="color:#008000;">//</span><span style="color:#008000;">模拟慢速的生产,产生阻塞的效果</span>} <span style="color:#0000ff;">catch</span><span style="color:#000000;"> (InterruptedException e1) {</span><span style="color:#008000;">//</span><span style="color:#008000;"> TODO Auto-generated catch block</span>

e1.printStackTrace();
}

     }  }

}

static class Consumer implements Runnable {
private String name;

 </span><span style="color:#0000ff;">public</span><span style="color:#000000;"> Consumer(String name) {  </span><span style="color:#0000ff;">this</span>.name =<span style="color:#000000;"> name;  }  </span><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> run() {  </span><span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = <span style="color:#800080;">1</span>; i &lt; <span style="color:#800080;">10</span>; ++<span style="color:#000000;">i) {  </span><span style="color:#0000ff;">try</span><span style="color:#000000;"> {          </span><span style="color:#008000;">//</span><span style="color:#008000;">必须要使用take()方法在获取的时候阻塞</span>System.<span style="color:#0000ff;">out</span>.println(name+<span style="color:#800000;">"</span><span style="color:#800000;">消费: </span><span style="color:#800000;">"</span> +<span style="color:#000000;">  concurrentLinkedQueue.take());  </span><span style="color:#008000;">//</span><span style="color:#008000;">使用poll()方法 将产生非阻塞效果</span><span style="color:#008000;">//</span><span style="color:#008000;">System.out.println(name+"消费: " +  concurrentLinkedQueue.poll());  </span><span style="color:#008000;">//</span><span style="color:#008000;">还有一个超时的用法,队列空时,指定阻塞时间后返回,不会一直阻塞</span><span style="color:#008000;">//</span><span style="color:#008000;">但有一个疑问,既然可以不阻塞,为啥还叫阻塞队列?</span><span style="color:#008000;">//</span><span style="color:#008000;">System.out.println(name+" Consumer " +  concurrentLinkedQueue.poll(300, TimeUnit.MILLISECONDS));                    </span>} <span style="color:#0000ff;">catch</span><span style="color:#000000;"> (Exception e) {</span><span style="color:#008000;">//</span><span style="color:#008000;"> TODO Auto-generated catch block</span>

e.printStackTrace();
}

     }  }

}
}

 

非阻塞队列

基于链接节点的、无界的、线程安全。此队列按照 FIFO(先进先出)原则对元素进行排序。队列的头部 是队列中时间最长的元素。队列的尾部 是队列中时间最短的元素。新的元素插入到队列的尾部,队列检索操作从队列头部获得元素。当许多线程共享访问一个公共 collection 时,ConcurrentLinkedQueue 是一个恰当的选择。此队列不允许 null 元素。

例子

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.TimeUnit;

public class NoBlockQueue {
private static ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<Integer>();

</span><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">static</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> main(String[] args) {  ExecutorService executorService </span>= Executors.newFixedThreadPool(<span style="color:#800080;">2</span><span style="color:#000000;">);  executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer1</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer2</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Producer(<span style="color:#800000;">"</span><span style="color:#800000;">producer3</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer1</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer2</span><span style="color:#800000;">"</span><span style="color:#000000;">));  executorService.submit(</span><span style="color:#0000ff;">new</span> Consumer(<span style="color:#800000;">"</span><span style="color:#800000;">consumer3</span><span style="color:#800000;">"</span><span style="color:#000000;">));  }  </span><span style="color:#0000ff;">static</span> <span style="color:#0000ff;">class</span><span style="color:#000000;"> Producer implements Runnable {  </span><span style="color:#0000ff;">private</span><span style="color:#000000;"> String name;  </span><span style="color:#0000ff;">public</span><span style="color:#000000;"> Producer(String name) {  </span><span style="color:#0000ff;">this</span>.name =<span style="color:#000000;"> name;  }  </span><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> run() {  </span><span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = <span style="color:#800080;">1</span>; i &lt; <span style="color:#800080;">10</span>; ++<span style="color:#000000;">i) {  System.</span><span style="color:#0000ff;">out</span>.println(name+ <span style="color:#800000;">"</span><span style="color:#800000;"> start producer </span><span style="color:#800000;">"</span> +<span style="color:#000000;"> i);  concurrentLinkedQueue.add(i);  </span><span style="color:#0000ff;">try</span><span style="color:#000000;"> {Thread.sleep(</span><span style="color:#800080;">20</span><span style="color:#000000;">);} </span><span style="color:#0000ff;">catch</span><span style="color:#000000;"> (InterruptedException e) {</span><span style="color:#008000;">//</span><span style="color:#008000;"> TODO Auto-generated catch block</span>

e.printStackTrace();
}
//System.out.println(name+"end producer " + i);
}
}
}

</span><span style="color:#0000ff;">static</span> <span style="color:#0000ff;">class</span><span style="color:#000000;"> Consumer implements Runnable {  </span><span style="color:#0000ff;">private</span><span style="color:#000000;"> String name;  </span><span style="color:#0000ff;">public</span><span style="color:#000000;"> Consumer(String name) {  </span><span style="color:#0000ff;">this</span>.name =<span style="color:#000000;"> name;  }  </span><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">void</span><span style="color:#000000;"> run() {  </span><span style="color:#0000ff;">for</span> (<span style="color:#0000ff;">int</span> i = <span style="color:#800080;">1</span>; i &lt; <span style="color:#800080;">10</span>; ++<span style="color:#000000;">i) {  </span><span style="color:#0000ff;">try</span><span style="color:#000000;"> {System.</span><span style="color:#0000ff;">out</span>.println(name+<span style="color:#800000;">"</span><span style="color:#800000;"> Consumer </span><span style="color:#800000;">"</span> +<span style="color:#000000;">  concurrentLinkedQueue.poll());} </span><span style="color:#0000ff;">catch</span><span style="color:#000000;"> (Exception e) {</span><span style="color:#008000;">//</span><span style="color:#008000;"> TODO Auto-generated catch block</span>

e.printStackTrace();
}
// System.out.println();
// System.out.println(name+" end Consumer " + i);
}
}
}
}

在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量地避免程序出现意外的错误。阻塞队列使用最经典的场景就是socket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。还有其他类似的场景,只要符合生产者-消费者模型的都可以使用阻塞队列。

使用非阻塞队列,虽然能即时返回结果(消费结果),但必须自行编码解决返回为空的情况处理(以及消费重试等问题)。

另外他们都是线程安全的,不用考虑线程同步问题。

JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别相关推荐

  1. java 多线程阻塞队列 与 阻塞方法与和非阻塞方法

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  2. 并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究

    并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究 http://www.importnew.com/25668.html 一. 前言 常用的并发队列有阻塞队列和非阻塞队列 ...

  3. 阻塞式IO和非阻塞式IO

    什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成" ...

  4. 深入理解非阻塞同步IO和非阻塞异步IO

    这两篇文章分析了Linux下的5种IO模型 http://blog.csdn.net/historyasamirror/article/details/5778378 http://blog.csdn ...

  5. 同步I/O、异步I/O、阻塞I/0、非阻塞I/O、五种I/O模型、高性能网络模型

    10.I/O相关概念 https://www.cnblogs.com/xiaoxi/p/6525396.html 10.1.同步和异步 ​ 同步就是:如果有多个任务或者事件要发生,这些任务或者事件必须 ...

  6. java socket nio 阻塞_Java NIO实现非阻塞式socket通信

    博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下:如果有dalao读到这儿,希望能指出理解中的问题~谢谢 Java提供了用于网络 ...

  7. java nio io复用_java 非阻塞IO-java NIO-嗨客网

    Java的NIO教程 NIO 官方名称叫做 New IO,在 JDK 1.4 中相对于 BIO 的新 IO.但是也有很多人称之为 NON-BLOCKING IO.和 BIO 比较的话,叫做非阻塞 IO ...

  8. java 非阻塞_Java之NIO(非阻塞IO)

    [1]NIO的与IO的区别: 总的来说java 中的IO 和NIO的区别主要有3点: 1)IO是面向流的,NIO是面向缓冲的: 2)IO是阻塞的,NIO是非阻塞的: 3)IO是单线程的,NIO 是通过 ...

  9. java实现非阻塞io原理_JAVA 非阻塞IO原理

    1.  基本概念 IO是主存和外部设备(硬盘.终端和网络等)传输数据的过程.IO是操作系统的底层功能实现,底层通过I/O指令进行完成. 2.nio简介 nio是java New IO的简称(并不只是指 ...

  10. 两段文章清楚弄明白什么是异步IO、同步IO、同步阻塞IO、同步非阻塞IO、异步阻塞IO、异步非阻塞IO

    百科解释:异步IO_百度百科 先看2,再看1,会理解的更好! 1. 2.阻塞和非阻塞 # 阻塞和非阻塞关注的是程序在等待调用结果时的状态 # 阻塞调用是指调用结果返回之前,当前线程会被挂起.调用线程只 ...

最新文章

  1. PS常用快捷键就这些了,记住绘图事半功倍
  2. 贴一段数组动态扩容的代码
  3. CIO实施精细化管理的五个要点
  4. [转] android获取手机信息大全
  5. 前端学习(1531):钩子函数--代码演示(面试重点)二
  6. 全网最好用的VS Code插件推荐
  7. 中缀表达式转后缀表达式(非常简单易懂)
  8. 【干货】区块链技术生态的设计|《白话区块链》作者蒋勇分享实录
  9. 台式计算机如何自动开关机,联想电脑怎么设置定时开机|联想台式机自动开机设置方法...
  10. 美术课上用计算机玩游戏,人教版一年级下册美术教案-07-乘上大船游世界
  11. HYSBZ 2818 Gcd
  12. RabbitMQ服务启动就自动停止解决方案
  13. java在线api中文_JAVA中英文API(在线版)
  14. IDEA 显示Cannot resolve plugin org.apache.maven.pluginsmaven-site-plugin3.3
  15. 系统性简述蓝牙以及ESP32对BLE蓝牙的使用(一)
  16. i7 10750h是标压吗 属于什么档次 i7 10750h天梯图
  17. 极大后验概率(MAP)- maximum a posteriori(转载)
  18. 【Java】工作流框架JBPM
  19. HTML(3):IE浏览器编程
  20. Unity中的射线检测

热门文章

  1. 【Oracle学习】archivelog
  2. 提高网页打开速度的一些小技巧
  3. Rxjs初体验:制作语音测试工具
  4. base64位 解码图片
  5. JAVA时间格式处理工具类
  6. 第8章 面向对象高级编程与网络编程
  7. 将 php 转换/编译为 EXE
  8. Linux如何使用GPG(GNU Privacy Guard)对信息/文件进行加密和解密
  9. RHCE 第三讲 文件系统
  10. 更新的ccna实训交换机基本配置(附图)