阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue
这两个队列都是线程安全的。
LinkedBlockingQueue:
public class LinkedBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, Serializable

此队列按 FIFO(先进先出)排序元素。队列的头部 是在队列中时间最长的元素。队列的尾部 是在队列中时间最短的元素。新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素。
链接队列的吞吐量通常要高于基于数组的队列,但是在大多数并发应用程序中,其可预知的性能要低。可选的容量范围构造方法参数作为防止队列过度扩展的一种方法。如果未指定容量,则它等于Integer.MAX_VALUE。除非插入节点会使队列超出容量,否则每次插入后会动态地创建链接节点。
适用阻塞队列的好处:多线程操作共同的队列时不需要额外的同步,另外就是队列会自动平衡负载,即那边(生产与消费两边)处理快了就会被阻塞掉,从而减少两边的处理速度差距。
Demo:
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; public class Main {
public static void main(String[] args) {
// 建立一个装苹果的篮子
Basket basket = new Basket();
ExecutorService service = Executors.newCachedThreadPool();
Producer producer = new Producer("生产者001", basket);
Producer producer2 = new Producer("生产者002", basket);
Consumer consumer = new Consumer("消费者001", basket);
service.submit(producer);
service.submit(producer2);
service.submit(consumer);
// 程序运行5s后,所有任务停止
try {
Thread.sleep(1000 * 5);
} catch (InterruptedException e) {
e.printStackTrace();
}
service.shutdownNow(); }
} /**
*
* 定义装苹果的篮子
*
*/
class Basket {
// 篮子,能够容纳3个苹果
BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3);
int i=0;
// 生产苹果,放入篮子
public void produce() throws InterruptedException {
// put方法放入一个苹果,若basket满了,等到basket有位置
i++;
basket.put("An apple"+i);
} // 消费苹果,从篮子中取走
public String consume() throws InterruptedException {
// take方法取出一个苹果,若basket为空,等到basket有苹果为止(获取并移除此队列的头部)
return basket.take();
}
} // 定义苹果生产者
class Producer implements Runnable {
private String instance;
private Basket basket; public Producer(String instance, Basket basket) {
this.instance = instance;
this.basket = basket;
} public void run() {
try {
while (true) {
// 生产苹果
System.out.println("生产者准备生产苹果:" + instance);
basket.produce();
System.out.println("!生产者生产苹果完毕:" + instance);
// 休眠300ms
Thread.sleep(300);
}
} catch (InterruptedException ex) {
System.out.println("Producer Interrupted");
}
}
} // 定义苹果消费者
class Consumer implements Runnable {
private String instance;
private Basket basket; public Consumer(String instance, Basket basket) {
this.instance = instance;
this.basket = basket;
} public void run() {
try {
while (true) {
// 消费苹果
System.out.println("消费者准备消费苹果:" + instance);
System.out.println(basket.consume());
System.out.println("!消费者消费苹果完毕:" + instance);
// 休眠1000ms
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
System.out.println("Consumer Interrupted");
}
}
}
生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
生产者准备生产苹果:生产者002
!生产者生产苹果完毕:生产者002
!生产者生产苹果完毕:生产者001
An apple1
!消费者消费苹果完毕:消费者001
生产者准备生产苹果:生产者001
生产者准备生产苹果:生产者002
!生产者生产苹果完毕:生产者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者001
生产者准备生产苹果:生产者002
消费者准备消费苹果:消费者001
An apple2
!生产者生产苹果完毕:生产者001
!消费者消费苹果完毕:消费者001
生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
An apple3
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者002
消费者准备消费苹果:消费者001
An apple4
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者001
生产者准备生产苹果:生产者001
消费者准备消费苹果:消费者001
An apple5
!消费者消费苹果完毕:消费者001
!生产者生产苹果完毕:生产者002
生产者准备生产苹果:生产者002
Producer Interrupted
Producer Interrupted
Consumer Interrupted
ConcurrentLinkedQueue:(http://blog.csdn.net/chenssy/article/details/74853120)
ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,它采用先进先出的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾部,当我们获取一个元素时,它会返回队列头部的元素。
使用并发队列,虽然能即时返回结果(消费结果),但必须自行编码解决返回为空的情况处理(以及消费重试等问题)。

代码:
package com.qhong; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(2); executorService.submit(new NoBlockQueue.Producer("producer1"));
executorService.submit(new NoBlockQueue.Producer("producer2"));
executorService.submit(new NoBlockQueue.Producer("producer3"));
executorService.submit(new NoBlockQueue.Consumer("consumer1"));
executorService.submit(new NoBlockQueue.Consumer("consumer2"));
executorService.submit(new NoBlockQueue.Consumer("consumer3"));
}
}
class NoBlockQueue {
private static ConcurrentLinkedQueue<Integer> concurrentLinkedQueue = new ConcurrentLinkedQueue<Integer>();
static class Producer implements Runnable {
private String name; public Producer(String name) {
this.name = name;
} public void run() {
for (int i = 1; i < 10; ++i) {
System.out.println(Thread.currentThread().getName()+"-----"+ name+ " start producer " + i);
concurrentLinkedQueue.add(i);
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} static class Consumer implements Runnable {
private String name; public Consumer(String name) {
this.name = name;
}
public void run() {
for (int i = 1; i < 10; ++i) {
try {
System.out.println(Thread.currentThread().getName()+"-----"+name+" Consumer " + concurrentLinkedQueue.poll());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
Output:
pool-1-thread-1-----producer1 start producer 1
pool-1-thread-2-----producer2 start producer 1
pool-1-thread-1-----producer1 start producer 2
pool-1-thread-2-----producer2 start producer 2
pool-1-thread-1-----producer1 start producer 3
pool-1-thread-2-----producer2 start producer 3
pool-1-thread-1-----producer1 start producer 4
pool-1-thread-2-----producer2 start producer 4
pool-1-thread-1-----producer1 start producer 5
pool-1-thread-2-----producer2 start producer 5
pool-1-thread-2-----producer2 start producer 6
pool-1-thread-2-----producer2 start producer 7
pool-1-thread-1-----producer1 start producer 6
pool-1-thread-2-----producer2 start producer 8
pool-1-thread-1-----producer1 start producer 7
pool-1-thread-2-----producer2 start producer 9
pool-1-thread-1-----producer1 start producer 8
pool-1-thread-1-----producer1 start producer 9
pool-1-thread-2-----producer3 start producer 1
pool-1-thread-1-----consumer1 Consumer 1
pool-1-thread-1-----consumer1 Consumer 1
pool-1-thread-1-----consumer1 Consumer 2
pool-1-thread-1-----consumer1 Consumer 2
pool-1-thread-1-----consumer1 Consumer 3
pool-1-thread-1-----consumer1 Consumer 3
pool-1-thread-1-----consumer1 Consumer 4
pool-1-thread-1-----consumer1 Consumer 4
pool-1-thread-1-----consumer1 Consumer 5
pool-1-thread-1-----consumer2 Consumer 5
pool-1-thread-1-----consumer2 Consumer 6
pool-1-thread-1-----consumer2 Consumer 7
pool-1-thread-1-----consumer2 Consumer 6
pool-1-thread-1-----consumer2 Consumer 8
pool-1-thread-1-----consumer2 Consumer 7
pool-1-thread-1-----consumer2 Consumer 9
pool-1-thread-1-----consumer2 Consumer 8
pool-1-thread-1-----consumer2 Consumer 9
pool-1-thread-1-----consumer3 Consumer 1
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-1-----consumer3 Consumer null
pool-1-thread-2-----producer3 start producer 2
pool-1-thread-2-----producer3 start producer 3
pool-1-thread-2-----producer3 start producer 4
pool-1-thread-2-----producer3 start producer 5
pool-1-thread-2-----producer3 start producer 6
pool-1-thread-2-----producer3 start producer 7
pool-1-thread-2-----producer3 start producer 8
pool-1-thread-2-----producer3 start producer 9
http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html
http://blog.csdn.net/ac903919/article/details/6967728
http://www.soso.io/article/66762.html
http://ifeve.com/concurrentlinkedqueue/
http://www.cnblogs.com/sunshine-2015/p/6067709.html
阻塞队列LinkedBlockingQueue和并发队列ConcurrentLinkedQueue的更多相关文章
- 并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别和使用场景总结
三者区别与联系: 联系,三者 都是线程安全的.区别,就是 并发 和 阻塞,前者为并发队列,因为采用cas算法,所以能够高并发的处理:后2者采用锁机制,所以是阻塞的.注意点就是前者由于采用cas算 ...
- 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和 使用场景总结 分类: Java2013-0 ...
- Java深入学习(2):并发队列
并发队列: 在并发队列中,JDK有两套实现: ConcurrentLinkedQueue:非阻塞式队列 BlockingQueue:阻塞式队列 阻塞式队列非阻塞式队列的区别: 阻塞式队列入列操作的时候 ...
- [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...
- 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...
- 并发队列ConcurrentLinkedQueue 和 阻塞队列LinkedBlockingQueue用法
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...
- 并发队列ConcurrentLinkedQueue与阻塞队列LinkedBlockingQueue的区别
1. 介绍背景 在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列. Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是Block ...
- (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
阻塞队列:线程安全 按 FIFO(先进先出)排序元素.队列的头部 是在队列中时间最长的元素.队列的尾部 是在队列中时间最短的元素.新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素.链接 ...
随机推荐
- eclipse 高亮配对的括号
在编辑代码框右键->preference,直接就可以看到Matching brackets highlights
- ubuntu13.04下安装jdk7
参考http://www.neversaydie.cc/ubuntu-install-jdk-in-detailed/ 而来 1.手工从Oralce官网下载jdk-7u25-linux-x64.gz ...
- 【BZOJ】1124: [POI2008]枪战Maf
题意 \(n(n < 1000000)\)个人,每个人\(i\)指向一个人\(p_i\),如果轮到\(i\)了且他没死,则他会将\(p_i\)打死.求一种顺序,问死的人最少和最多的数目. 分析 ...
- 【POJ】3678 Katu Puzzle
http://poj.org/problem?id=3678 题意:很幼稚的题目直接看英文题面= = #include <cstdio> #include <cstring> ...
- iOS 中实现功能引导页面
// // guideView.h // 07-功能引导-李洪强 // // Created by vic fan on 16/1/4. // Copyright © 2016年 李洪强. A ...
- [VBA] 打开文件夹
'显示打开文件夹对话框 With Application.FileDialog(msoFileDialogFolderPicker) .Show Then Exit Sub '未选择文件夹 strFo ...
- 解析私有IP地址和公网IP地址
局域网私有IP地址上外网的原理 IP地址分为两部分,网络号和主机号,这种分法应用在私有和公有IP地址上.一个局域网中,为了该局域网的安全,我们应用了私有IP地址,为了和Internet中的其他主机进行 ...
- Bootstrap css背景图片的设置
一. 网页中添加图片的方式有两种 一种是:通过<img>标签直接插入到html中 另一种是:通过css背景属性添加 居中方法:水平居中的text-align:center 和 margin ...
- 修改SQL Server 2005 数据库文件名字
对于SQLServer 2005的数据库文件名字的修改.不多说,见图: 对于数据库名的更改直接选中要修改的数据库,F2,你懂的,不懂的可以去屎了.....0.0 下面要修改数据库的文件名 原理就是利用 ...
- 深入理解C++虚函数表
虚函数表是C++类中存放虚函数的一张表,理解虚函数表对于理解多态很重要. 本次使用的编译器是VS2013,为了简化操作,不用去操作函数指针,我使用到了VS的CL编译选项来查看类的内存布局. CL使用方 ...