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. 系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体

    系统管理模块_岗位管理_实现CRUD功能的具体步骤并设计Role实体 1,设计实体/表 设计实体 --> JavaBean --> hbm.xml --> 建表 设计Role实体 p ...

  2. shell脚本学习总结08--比较与测试

    程序中流程控制是由比较语句和测试语句处理的 算数比较 [ $var -gt 20 ] [ $var -gt 20 -a $var -lt 50 ]         #使用逻辑与 [ $var -ne ...

  3. js(jQuery)相关随笔

    //获取所有name='id'.被选择的的多选框var idArr = $("input[type='checkbox'][name='id']:checked");//将这些多选 ...

  4. 使用jquery-qrcode生成二维码(转载)

    一.使用jquery-qrcode生成二维码 先简单说一下jquery-qrcode,这个开源的三方库(可以从https://github.com/jeromeetienne/jquery-qrcod ...

  5. fieldmeta 基于springboot的字段元数据管理,通用代码生成,快速开发引擎

    fieldmeta: 基于springboot的字段元数据管理 version:Alpha 0.0.1 ,码云地址:https://gitee.com/klguang/fieldmeta 元数据(Me ...

  6. Bootstrap中关于input里file的样式更改

    给input里file类型加button样式 1.在Bootstrap中input里的file类型样式很不美观,一个按钮加一段文字,还会随浏览器的不同呈现不同的样式,所以开发的时候可以将file的样式 ...

  7. Exchange Database Status(Copy Status ,Content Index State,QueueLength,Move Status...)

    Copy Status Description Mounted The active copy is online and accepting client connections. Only the ...

  8. 阿里云OSS分片上传DEMO

    分片传输规则 1.不能超过10000片,2.每片必须大于100KB using System; using System.Collections.Generic; using System.Compo ...

  9. 如何查看电脑最大支持多少GB内存

    第一种方法: 1.打开“开始”菜单,点击“运行”按钮,也可以直接使用[Win + R]组合快捷键打开, 在弹出来的窗口输入“CMD”,然后确定或者按下回车键 2.在命令窗口输入“wmic memphy ...

  10. Linux时间管理涉及数据结构和传统低分辨率时钟的实现

    上篇文章大致描述了Linux时间管理的基本情况,看了一些大牛们的博客感觉自己写的内容很匮乏,但是没办法,只能通过这种方式提升自己……闲话不说,本节介绍下时间管理下重要的数据结构 设备相关数据结构 // ...