这两个队列都是线程安全的。
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