并发队列ConcurrentLinkedQueue与阻塞队列LinkedBlockingQueue的区别
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的区别的更多相关文章
- 自己总结 :并发队列ConcurrentLinkedQueue、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别 和 使用场景总结
并发队列ConcurrentLinkedQueue.阻塞队列AraayBlockingQueue.阻塞队列LinkedBlockingQueue 区别 和 使用场景总结 分类: Java2013-0 ...
- [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、阻塞队列AraayBlockingQueue、阻塞队列LinkedBlockingQueue 区别和使用场景总结
三者区别与联系: 联系,三者 都是线程安全的.区别,就是 并发 和 阻塞,前者为并发队列,因为采用cas算法,所以能够高并发的处理:后2者采用锁机制,所以是阻塞的.注意点就是前者由于采用cas算 ...
- 并发编程学习笔记(13)----ConcurrentLinkedQueue(非阻塞队列)和BlockingQueue(阻塞队列)原理
· 在并发编程中,我们有时候会需要使用到线程安全的队列,而在Java中如果我们需要实现队列可以有两种方式,一种是阻塞式队列.另一种是非阻塞式的队列,阻塞式队列采用锁来实现,而非阻塞式队列则是采用cas ...
- 细说并发5:Java 阻塞队列源码分析(下)
上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...
- 细说并发4:Java 阻塞队列源码分析(上)
上篇文章 趣谈并发3:线程池的使用与执行流程 中我们了解到,线程池中需要使用阻塞队列来保存待执行的任务.这篇文章我们来详细了解下 Java 中的阻塞队列究竟是什么. 读完你将了解: 什么是阻塞队列 七 ...
随机推荐
- soundpool播放声音
一般大家使用的是MediaPlayer来播放音频,它的创建和销毁都是非常消耗资源的,如果我们的需求是播放一些短促而且频繁播放的音频的话MediaPlayer就有些不合适了,我们来讲讲SoundPool ...
- 通过AnimationSet 同步或一部播放多个动画 Android 属性动画(Property Animation) 完全解析 (下)
AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等. 以下例子同时应用5个动画: 播放anim1: 同时播放anim2,anim3,a ...
- LeetCode-Water and Jug Problem
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- vue 添加过滤器-以格式化日期为例
vue的filter和angular的pipe管道类似,是过滤器 官网:https://cn.vuejs.org/v2/guide/filters.html 添加格式化日期的全局过滤器 在main.j ...
- maven发布项目的snapshot到nexus
1.配置发布地址信息 <repositories> <repository> <id>nexus</id> <name>Local Repo ...
- dao---service---action分层结构
此文转载于http://blog.csdn.net/jay198746/article/details/4698709 之前有看过一些ssh2中采用dao---service---action分层结构 ...
- CodeForces 24D Broken robot (概率DP)
D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- CH5E01 乌龟棋【线性DP】
5E01 乌龟棋 0x5E「动态规划」练习 描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物.乌龟棋的棋盘是一行N 个格子,每个格子上一个分数(非负整数).棋盘第1 格是唯一的起点,第N 格是终点 ...
- qt model view 编程总结
看不见的root的 QModelIndex() 是 无效的 list 和table 的index 函数中的parent参数就只要 root QModelIndex 就可以,因为没有层级概念 Model ...
- access join形式删除数据
--注意distinctrow关键字 delete distinctrow a.* from aa a inner join bb b on a.id= b.id