1.  介绍背景

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。

Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。

2. LinkedBlockingQueue

由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。

package com.lky.test;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.junit.Test; /**
* @Title: testBlockQueue.java
* @Package com.lky.test
* @Description:多线程模拟实现生产者消费者模型(阻塞队列)
* @author lky
* @date 2015年10月24日 下午5:08:01
* @version V1.0
*/
public class testBlockQueue { private Log log = LogFactory.getLog(testBlockQueue.class); /**
* @Title: testBlockQueue.java
* @Package com.lky.test
* @Description: 定义阻塞队列
* @author lky
* @date 2015年10月24日 下午5:07:28
* @version V1.0
*/
public class Basket {
// 队列的最大容量为3
BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3); // 如果队列不满,则放入,否则阻塞等待
public void produce(String apple) throws InterruptedException {
basket.put(apple);
} // 如果队列不为空,则取出,否则阻塞等待
public String consumer() throws InterruptedException {
return basket.take();
}
} /**
* @Title: testBlockQueue.java
* @Package com.lky.test
* @Description: 定义生产者
* @author lky
* @date 2015年10月24日 下午5:18:17
* @version V1.0
*/
public class Produce implements Runnable {
private Basket basket;
private String fruit; public Produce(String fruit, Basket basket) {
this.basket = basket;
this.fruit = fruit;
} @Override
public void run() {
try {
while (true) {
log.info("[" + Thread.currentThread().getName() + "]" + "开始生产apple----->" + this.fruit);
basket.produce(fruit);
log.info("apple生产完毕!!!!");
Thread.sleep(1000);
}
} catch (Exception e) {
log.error("生产苹果异常!!!!!");
}
}
} /**
* @Title: testBlockQueue.java
* @Package com.lky.test
* @Description: 定义消费者
* @author lky
* @date 2015年10月24日 下午5:24:31
* @version V1.0
*/
public class Consumer implements Runnable {
private Basket basket; public Consumer(Basket basket) {
this.basket = basket;
} @Override
public void run() {
try {
while (true) {
String fruit = basket.consumer();
log.info("[" + Thread.currentThread().getName() + "]" + "取到一个水果: " + fruit);
Thread.sleep(1000);
} } catch (Exception e) {
log.error("消费者取苹果异常!!!!");
}
}
} @Test
public void test() {
System.out.println(Runtime.getRuntime().availableProcessors());//获取当前系统的cpu数目 Basket basket = new Basket();
Produce produce1 = new Produce("apple", basket);
Produce produce2 = new Produce("banna", basket);
Consumer consumer = new Consumer(basket); // 新建一个线程池
ExecutorService service = Executors.newCachedThreadPool(); service.submit(produce1);
service.submit(produce2);
service.submit(consumer); try {
Thread.sleep(20000);
} catch (Exception e) {
log.error("程序异常错误!!!!");
}
service.shutdown();
}
}

3. ConcurrentLinkedQueue

是Queue的一个安全实现.Queue中元素按FIFO原则进行排序.采用CAS操作,来保证元素的一致性。

package com.lky.test;

import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; /**
* @Title: testNBlockQueue.java
* @Package com.lky.test
* @Description: 多线程模拟实现生产者消费者模型(非阻塞式队列)
* @author lky
* @date 2015年10月24日 下午8:02:14
* @version V1.0
*/
public class testNBlockQueue {
private static Log log = LogFactory.getLog(testNBlockQueue.class);
private static ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>(); private static int count = 2;
private static CountDownLatch latch = new CountDownLatch(count); private static class Poll implements Runnable {
@Override
public void run() {
while (!queue.isEmpty()) {
log.info(Thread.currentThread().getName() + "消费一个商品: " + queue.poll());
}
latch.countDown();
}
} public static void main(String args[]) throws InterruptedException {
long timeStart = System.currentTimeMillis();
ExecutorService eService = Executors.newFixedThreadPool(4); // 生产商品
for (int i = 0; i < 100000; ++i) {
queue.offer(i);
} // 消费者
for (int i = 0; i < count; ++i) {
eService.submit(new Poll());
} latch.await();// 使得主线程阻塞,直到latch.getCount()为0
System.out.println("Cost time: " + (System.currentTimeMillis() - timeStart));
eService.shutdown();
}
}

4. 使用场景

在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出)。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。

并发队列ConcurrentLinkedQueue与阻塞队列LinkedBlockingQueue的区别的更多相关文章

  1. 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结

    并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和  使用场景总结 分类: Java2013-0 ...

  2. [Java 基础] 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    reference : http://www.cnblogs.com/linjiqin/archive/2013/05/30/3108188.html 在Java多线程应用中,队列的使用率很高,多数生 ...

  3. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  4. 并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法(转)

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  5. 并发队列ConcurrentLinkedQueue 和 阻塞队列LinkedBlockingQueue用法

    在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列(先进先出).Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQ ...

  6. 并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别和使用场景总结

      三者区别与联系: 联系,三者 都是线程安全的.区别,就是 并发  和 阻塞,前者为并发队列,因为采用cas算法,所以能够高并发的处理:后2者采用锁机制,所以是阻塞的.注意点就是前者由于采用cas算 ...

  7. 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理

    · 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...

  8. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  9. 细说并发4:Java 阻塞队列源码分析(上)

    上篇文章 趣谈并发3:线程池的使用与执行流程 中我们了解到,线程池中需要使用阻塞队列来保存待执行的任务.这篇文章我们来详细了解下 Java 中的阻塞队列究竟是什么. 读完你将了解: 什么是阻塞队列 七 ...

随机推荐

  1. java对象和json数据转换实现方式3-使用jackson实现

    測试代码: package com.yanek.util.json; import java.io.IOException; import java.io.StringWriter; import j ...

  2. [SDOI2016 Round1] 征途[斜率优化]

    2225. [SDOI2016 Round1] 征途 ★★★☆   输入文件:menci_journey.in   输出文件:menci_journey.out   简单对比时间限制:1 s   内存 ...

  3. python反序列化研究学习

    零.补充: 补充于2018-02-08,之前研究时候有一个疑惑,python的序列化成二进制,打web服务怎么传这个二进制对象呢,今天请教了身边大神(传说的九零后黑客代表),可以使用base64传输. ...

  4. 帧动画和骨骼json、极速、二进制对比

    对比总结: 1. 帧动画的效率最高,但是图片超过一定帧数,资源图片非常大.比较适合帧数少,大量动画存在,要求效率高的场合. 骨骼json效率较低,已经不推荐使用. 骨骼极速,不支持网格等. 骨骼二进制 ...

  5. 【BZOJ4551】[Tjoi2016&Heoi2016]树 并查集

    [BZOJ4551][Tjoi2016&Heoi2016]树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为1),有以下两 ...

  6. 【BZOJ4518】[Sdoi2016]征途 斜率优化

    [BZOJ4518][Sdoi2016]征途 Description Pine开始了从S地到T地的征途. 从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站. Pine计划用m天到达T地.除 ...

  7. c#获取QQ音乐当前播放的歌曲名

    在网上找了很久,没找到方法,自己尝试着做,还是做出来了,很简单,就几句代码. Process[] ps = Process.GetProcessesByName("QQmusic" ...

  8. jmeter常见参数 vars、prev、ctx 、props 类的api

    ctx - ( JMeterContext) - gives access to the context vars - ( JMeterVariables) - gives read/write ac ...

  9. 解决64位debian下无法安装ia32库的问题

    原文地址:http://crunchbang.org/forums/viewtopic.php?pid=277918 因为64位debian源中并没有包括32位的软件包,所提安装ia32会提示依赖无法 ...

  10. Spark源码分析 – Dependency

    Dependency 依赖, 用于表示RDD之间的因果关系, 一个dependency表示一个parent rdd, 所以在RDD中使用Seq[Dependency[_]]来表示所有的依赖关系 Dep ...