JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
阻塞队列:线程安全
按 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 < <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 < <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 < <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 < <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 的区别相关推荐
- java 多线程阻塞队列 与 阻塞方法与和非阻塞方法
Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...
- 并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究
并发队列-无界非阻塞队列 ConcurrentLinkedQueue 原理探究 http://www.importnew.com/25668.html 一. 前言 常用的并发队列有阻塞队列和非阻塞队列 ...
- 阻塞式IO和非阻塞式IO
什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成" ...
- 深入理解非阻塞同步IO和非阻塞异步IO
这两篇文章分析了Linux下的5种IO模型 http://blog.csdn.net/historyasamirror/article/details/5778378 http://blog.csdn ...
- 同步I/O、异步I/O、阻塞I/0、非阻塞I/O、五种I/O模型、高性能网络模型
10.I/O相关概念 https://www.cnblogs.com/xiaoxi/p/6525396.html 10.1.同步和异步 同步就是:如果有多个任务或者事件要发生,这些任务或者事件必须 ...
- java socket nio 阻塞_Java NIO实现非阻塞式socket通信
博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下:如果有dalao读到这儿,希望能指出理解中的问题~谢谢 Java提供了用于网络 ...
- java nio io复用_java 非阻塞IO-java NIO-嗨客网
Java的NIO教程 NIO 官方名称叫做 New IO,在 JDK 1.4 中相对于 BIO 的新 IO.但是也有很多人称之为 NON-BLOCKING IO.和 BIO 比较的话,叫做非阻塞 IO ...
- java 非阻塞_Java之NIO(非阻塞IO)
[1]NIO的与IO的区别: 总的来说java 中的IO 和NIO的区别主要有3点: 1)IO是面向流的,NIO是面向缓冲的: 2)IO是阻塞的,NIO是非阻塞的: 3)IO是单线程的,NIO 是通过 ...
- java实现非阻塞io原理_JAVA 非阻塞IO原理
1. 基本概念 IO是主存和外部设备(硬盘.终端和网络等)传输数据的过程.IO是操作系统的底层功能实现,底层通过I/O指令进行完成. 2.nio简介 nio是java New IO的简称(并不只是指 ...
- 两段文章清楚弄明白什么是异步IO、同步IO、同步阻塞IO、同步非阻塞IO、异步阻塞IO、异步非阻塞IO
百科解释:异步IO_百度百科 先看2,再看1,会理解的更好! 1. 2.阻塞和非阻塞 # 阻塞和非阻塞关注的是程序在等待调用结果时的状态 # 阻塞调用是指调用结果返回之前,当前线程会被挂起.调用线程只 ...
最新文章
- PS常用快捷键就这些了,记住绘图事半功倍
- 贴一段数组动态扩容的代码
- CIO实施精细化管理的五个要点
- [转] android获取手机信息大全
- 前端学习(1531):钩子函数--代码演示(面试重点)二
- 全网最好用的VS Code插件推荐
- 中缀表达式转后缀表达式(非常简单易懂)
- 【干货】区块链技术生态的设计|《白话区块链》作者蒋勇分享实录
- 台式计算机如何自动开关机,联想电脑怎么设置定时开机|联想台式机自动开机设置方法...
- 美术课上用计算机玩游戏,人教版一年级下册美术教案-07-乘上大船游世界
- HYSBZ 2818 Gcd
- RabbitMQ服务启动就自动停止解决方案
- java在线api中文_JAVA中英文API(在线版)
- IDEA 显示Cannot resolve plugin org.apache.maven.pluginsmaven-site-plugin3.3
- 系统性简述蓝牙以及ESP32对BLE蓝牙的使用(一)
- i7 10750h是标压吗 属于什么档次 i7 10750h天梯图
- 极大后验概率(MAP)- maximum a posteriori(转载)
- 【Java】工作流框架JBPM
- HTML(3):IE浏览器编程
- Unity中的射线检测