1.  介绍背景

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

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

2. LinkedBlockingQueue

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

  1. package com.lky.test;
  2.  
  3. import java.util.concurrent.BlockingQueue;
  4. import java.util.concurrent.ExecutorService;
  5. import java.util.concurrent.Executors;
  6. import java.util.concurrent.LinkedBlockingQueue;
  7.  
  8. import org.apache.commons.logging.Log;
  9. import org.apache.commons.logging.LogFactory;
  10.  
  11. import org.junit.Test;
  12.  
  13. /**
  14. * @Title: testBlockQueue.java
  15. * @Package com.lky.test
  16. * @Description:多线程模拟实现生产者消费者模型(阻塞队列)
  17. * @author lky
  18. * @date 2015年10月24日 下午5:08:01
  19. * @version V1.0
  20. */
  21. public class testBlockQueue {
  22.  
  23. private Log log = LogFactory.getLog(testBlockQueue.class);
  24.  
  25. /**
  26. * @Title: testBlockQueue.java
  27. * @Package com.lky.test
  28. * @Description: 定义阻塞队列
  29. * @author lky
  30. * @date 2015年10月24日 下午5:07:28
  31. * @version V1.0
  32. */
  33. public class Basket {
  34. // 队列的最大容量为3
  35. BlockingQueue<String> basket = new LinkedBlockingQueue<String>(3);
  36.  
  37. // 如果队列不满,则放入,否则阻塞等待
  38. public void produce(String apple) throws InterruptedException {
  39. basket.put(apple);
  40. }
  41.  
  42. // 如果队列不为空,则取出,否则阻塞等待
  43. public String consumer() throws InterruptedException {
  44. return basket.take();
  45. }
  46. }
  47.  
  48. /**
  49. * @Title: testBlockQueue.java
  50. * @Package com.lky.test
  51. * @Description: 定义生产者
  52. * @author lky
  53. * @date 2015年10月24日 下午5:18:17
  54. * @version V1.0
  55. */
  56. public class Produce implements Runnable {
  57. private Basket basket;
  58. private String fruit;
  59.  
  60. public Produce(String fruit, Basket basket) {
  61. this.basket = basket;
  62. this.fruit = fruit;
  63. }
  64.  
  65. @Override
  66. public void run() {
  67. try {
  68. while (true) {
  69. log.info("[" + Thread.currentThread().getName() + "]" + "开始生产apple----->" + this.fruit);
  70. basket.produce(fruit);
  71. log.info("apple生产完毕!!!!");
  72. Thread.sleep(1000);
  73. }
  74. } catch (Exception e) {
  75. log.error("生产苹果异常!!!!!");
  76. }
  77. }
  78. }
  79.  
  80. /**
  81. * @Title: testBlockQueue.java
  82. * @Package com.lky.test
  83. * @Description: 定义消费者
  84. * @author lky
  85. * @date 2015年10月24日 下午5:24:31
  86. * @version V1.0
  87. */
  88. public class Consumer implements Runnable {
  89. private Basket basket;
  90.  
  91. public Consumer(Basket basket) {
  92. this.basket = basket;
  93. }
  94.  
  95. @Override
  96. public void run() {
  97. try {
  98. while (true) {
  99. String fruit = basket.consumer();
  100. log.info("[" + Thread.currentThread().getName() + "]" + "取到一个水果: " + fruit);
  101. Thread.sleep(1000);
  102. }
  103.  
  104. } catch (Exception e) {
  105. log.error("消费者取苹果异常!!!!");
  106. }
  107. }
  108. }
  109.  
  110. @Test
  111. public void test() {
  112. System.out.println(Runtime.getRuntime().availableProcessors());//获取当前系统的cpu数目
  113.  
  114. Basket basket = new Basket();
  115. Produce produce1 = new Produce("apple", basket);
  116. Produce produce2 = new Produce("banna", basket);
  117. Consumer consumer = new Consumer(basket);
  118.  
  119. // 新建一个线程池
  120. ExecutorService service = Executors.newCachedThreadPool();
  121.  
  122. service.submit(produce1);
  123. service.submit(produce2);
  124. service.submit(consumer);
  125.  
  126. try {
  127. Thread.sleep(20000);
  128. } catch (Exception e) {
  129. log.error("程序异常错误!!!!");
  130. }
  131. service.shutdown();
  132. }
  133. }

3. ConcurrentLinkedQueue

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

  1. package com.lky.test;
  2.  
  3. import java.util.concurrent.ConcurrentLinkedQueue;
  4. import java.util.concurrent.CountDownLatch;
  5. import java.util.concurrent.ExecutorService;
  6. import java.util.concurrent.Executors;
  7.  
  8. import org.apache.commons.logging.Log;
  9. import org.apache.commons.logging.LogFactory;
  10.  
  11. /**
  12. * @Title: testNBlockQueue.java
  13. * @Package com.lky.test
  14. * @Description: 多线程模拟实现生产者消费者模型(非阻塞式队列)
  15. * @author lky
  16. * @date 2015年10月24日 下午8:02:14
  17. * @version V1.0
  18. */
  19. public class testNBlockQueue {
  20. private static Log log = LogFactory.getLog(testNBlockQueue.class);
  21. private static ConcurrentLinkedQueue<Integer> queue = new ConcurrentLinkedQueue<Integer>();
  22.  
  23. private static int count = 2;
  24. private static CountDownLatch latch = new CountDownLatch(count);
  25.  
  26. private static class Poll implements Runnable {
  27. @Override
  28. public void run() {
  29. while (!queue.isEmpty()) {
  30. log.info(Thread.currentThread().getName() + "消费一个商品: " + queue.poll());
  31. }
  32. latch.countDown();
  33. }
  34. }
  35.  
  36. public static void main(String args[]) throws InterruptedException {
  37. long timeStart = System.currentTimeMillis();
  38. ExecutorService eService = Executors.newFixedThreadPool(4);
  39.  
  40. // 生产商品
  41. for (int i = 0; i < 100000; ++i) {
  42. queue.offer(i);
  43. }
  44.  
  45. // 消费者
  46. for (int i = 0; i < count; ++i) {
  47. eService.submit(new Poll());
  48. }
  49.  
  50. latch.await();// 使得主线程阻塞,直到latch.getCount()为0
  51. System.out.println("Cost time: " + (System.currentTimeMillis() - timeStart));
  52. eService.shutdown();
  53. }
  54. }

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. soundpool播放声音

    一般大家使用的是MediaPlayer来播放音频,它的创建和销毁都是非常消耗资源的,如果我们的需求是播放一些短促而且频繁播放的音频的话MediaPlayer就有些不合适了,我们来讲讲SoundPool ...

  2. 通过AnimationSet 同步或一部播放多个动画 Android 属性动画(Property Animation) 完全解析 (下)

    AnimationSet提供了一个把多个动画组合成一个组合的机制,并可设置组中动画的时序关系,如同时播放,顺序播放等. 以下例子同时应用5个动画: 播放anim1: 同时播放anim2,anim3,a ...

  3. 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 ...

  4. vue 添加过滤器-以格式化日期为例

    vue的filter和angular的pipe管道类似,是过滤器 官网:https://cn.vuejs.org/v2/guide/filters.html 添加格式化日期的全局过滤器 在main.j ...

  5. maven发布项目的snapshot到nexus

    1.配置发布地址信息 <repositories> <repository> <id>nexus</id> <name>Local Repo ...

  6. dao---service---action分层结构

    此文转载于http://blog.csdn.net/jay198746/article/details/4698709 之前有看过一些ssh2中采用dao---service---action分层结构 ...

  7. CodeForces 24D Broken robot (概率DP)

    D. Broken robot time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  8. CH5E01 乌龟棋【线性DP】

    5E01 乌龟棋 0x5E「动态规划」练习 描述 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物.乌龟棋的棋盘是一行N 个格子,每个格子上一个分数(非负整数).棋盘第1 格是唯一的起点,第N 格是终点 ...

  9. qt model view 编程总结

    看不见的root的 QModelIndex() 是 无效的 list 和table 的index 函数中的parent参数就只要 root QModelIndex 就可以,因为没有层级概念 Model ...

  10. access join形式删除数据

    --注意distinctrow关键字 delete distinctrow a.* from aa a inner join bb b on a.id= b.id