阻塞队列:线程安全

按 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(); executorService.submit(new Producer("producer1"));
executorService.submit(new Producer("producer2"));
executorService.submit(new Producer("producer3"));
executorService.submit(new Consumer("consumer1"));
executorService.submit(new Consumer("consumer2"));
executorService.submit(new Consumer("consumer3")); } static class Producer implements Runnable {
private String name; public Producer(String name) {
this.name = name;
} public void run() {
for (int i = ; i < ; ++i) {
System.out.println(name+ " 生产: " + i);
//concurrentLinkedQueue.add(i);
try {
concurrentLinkedQueue.put(i);
Thread.sleep(); //模拟慢速的生产,产生阻塞的效果
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} }
}
} static class Consumer implements Runnable {
private String name; public Consumer(String name) {
this.name = name;
}
public void run() {
for (int i = ; i < ; ++i) {
try {
//必须要使用take()方法在获取的时候阻塞
System.out.println(name+"消费: " + concurrentLinkedQueue.take());
//使用poll()方法 将产生非阻塞效果
//System.out.println(name+"消费: " + concurrentLinkedQueue.poll()); //还有一个超时的用法,队列空时,指定阻塞时间后返回,不会一直阻塞
//但有一个疑问,既然可以不阻塞,为啥还叫阻塞队列?
//System.out.println(name+" Consumer " + concurrentLinkedQueue.poll(300, TimeUnit.MILLISECONDS));
} catch (Exception e) {
// TODO Auto-generated catch block
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>(); public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(); executorService.submit(new Producer("producer1"));
executorService.submit(new Producer("producer2"));
executorService.submit(new Producer("producer3"));
executorService.submit(new Consumer("consumer1"));
executorService.submit(new Consumer("consumer2"));
executorService.submit(new Consumer("consumer3")); } static class Producer implements Runnable {
private String name; public Producer(String name) {
this.name = name;
} public void run() {
for (int i = ; i < ; ++i) {
System.out.println(name+ " start producer " + i);
concurrentLinkedQueue.add(i);
try {
Thread.sleep();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println(name+"end producer " + i);
}
}
} static class Consumer implements Runnable {
private String name; public Consumer(String name) {
this.name = name;
}
public void run() {
for (int i = ; i < ; ++i) {
try { System.out.println(name+" Consumer " + concurrentLinkedQueue.poll()); } catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// System.out.println();
// System.out.println(name+" end Consumer " + i);
}
}
}
}

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

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

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

(原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别的更多相关文章

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

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

  2. 29、Java并发性和多线程-非阻塞算法

    以下内容转自http://ifeve.com/non-blocking-algorithms/: 在并发上下文中,非阻塞算法是一种允许线程在阻塞其他线程的情况下访问共享状态的算法.在绝大多数项目中,在 ...

  3. Java IO(3)非阻塞式输入输出(NIO)

    在上篇<Java IO(2)阻塞式输入输出(BIO)>的末尾谈到了什么是阻塞式输入输出,通过Socket编程对其有了大致了解.现在再重新回顾梳理一下,对于只有一个“客户端”和一个“服务器端 ...

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

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

  5. 阻塞I/O、非阻塞I/O和I/O多路复用、怎样理解阻塞非阻塞与同步异步的区别?

    “阻塞”与"非阻塞"与"同步"与“异步"不能简单的从字面理解,提供一个从分布式系统角度的回答.1.同步与异步 同步和异步关注的是消息通信机制 (syn ...

  6. php使用flock阻塞写入文件和非阻塞写入文件的实例讲解

    php使用flock阻塞写入文件和非阻塞写入文件的实例讲解: 阻塞写入代码:(所有程序会等待上次程序执行结束才会执行,30秒会超时) <?php $file = fopen("test ...

  7. 同步I/O、异步I/O与阻塞I/O、非阻塞I/O的区别

    一.I/O I/O (Input/Output,输入/输出)即数据的读取(接收)或写入(发送)操作. 通常用户进程中的一个完整I/O分为两阶段:用户进程空间<-->内核空间.内核空间< ...

  8. Python之阻塞IO模型与非阻塞IO模型

    Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...

  9. 转:IO模型-- 同步和阻塞,异步和非阻塞的区别

    源地址 http://hi.baidu.com/deep_pro/item/db0c581af1c1f17e7b5f2534 这些词之间的区别难倒了很多人,还有什么同步阻塞, 同步非阻塞, 异步阻塞, ...

随机推荐

  1. pyspider示例代码五:实现自动翻页功能

    实现自动翻页功能 示例代码一 #!/usr/bin/env python # -*- encoding: utf- -*- # Created on -- :: # Project: v2ex fro ...

  2. Linux应用开发入门(转)

    今天偶然看到这篇文章,做个入门了解还是不错的. 前一阵子在QQ上和朋友聊天的时候,总会看到有人说Linux上的应用程序开发是高手才可以完成的,而且这种“迷信”在目前似乎还很普遍.然而,情况并不是这样的 ...

  3. 2018.08.30 花园(期望dp)

    题目背景 SCOI2017 DAY2 T1 题目描述 小 A 的花园的长和宽分别是 L,H .小 A 喜欢在花园里做游戏.每次做游戏的时候,他都先把花园均匀分割成 L×H 个小方块,每个方块的长和宽都 ...

  4. Docker mysql启动自动按顺序导入sql

    1.目录结构 -rw-r--r-- root root Jan : Dockerfile -rw-r--r-- root root Jan : initdb.sh drwxr-xr-x root ro ...

  5. 动态渲染的input怎么取消记忆功能

    方法1 :自定义去除记忆功能属性: $('#index_table_filter > label > input[type="search"]').attr('auto ...

  6. MATLAB矩阵的一些用法

    1.怎样去提取和修改矩阵中的一个元素. (1)创建一个矩阵 >> A=[1,2,3,4;5,6,7,8;9,10,11,12;13,14,15,16]A =     1     2     ...

  7. Sublime必用快捷键[私人]

    最近一年前端开发都是用sublime这款编辑器, 相对于webStorm强大而启动慢.editplus快启动而功能弱, sublime恰好在两者之间:而且其指令行安装.更新.卸载插件比eclipse之 ...

  8. (欧拉公式 很水) Coprimes -- sgu -- 1002

    链接: http://vj.acmclub.cn/contest/view.action?cid=168#problem/B Coprimes 时限:250MS     内存:4096KB     6 ...

  9. 使用for in循环遍历json对象的数据

    使用for in遍历json对象数据,如果数据中的名称有为数字的话,只对正整数有效,那么先会输出为正整数的数据,后面其他的会按照原来数据中定义的顺序不变输出. 针对名称为数字的json对象数据进行测试 ...

  10. [leetcode] 18. Length of Last Word

    这个题目很简单,给一个字符串,然后返回最后一个单词的长度就行.题目如下: Given a string s consists of upper/lower-case alphabets and emp ...