BlockingQueue也是java.util.concurrent下的主要用来控制线程同步的工具。
BlockingQueue有四个具体的实现类,根据不同需求,选择不同的实现类
1、ArrayBlockingQueue:一个由数组支持的有界阻塞队列,规定大小的BlockingQueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以FIFO(先入先出)顺序排序的。
2、LinkedBlockingQueue:大小不定的BlockingQueue,若其构造函数带一个规定大小的参数,生成的BlockingQueue有大小限制,若不带大小参数,所生成的BlockingQueue的大小由Integer.MAX_VALUE来决定.其所含的对象是以FIFO(先入先出)顺序排序的。
3、PriorityBlockingQueue:类似于LinkedBlockQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数的Comparator决定的顺序。
4、SynchronousQueue:特殊的BlockingQueue,对其的操作必须是放和取交替完成的。
LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
生产者消费者的示例代码:
1 package com.xt.thinks21_7; 2 3 import java.util.concurrent.BlockingQueue; 4 import java.util.concurrent.ExecutorService; 5 import java.util.concurrent.Executors; 6 import java.util.concurrent.LinkedBlockingDeque; 7 8 /** 9 * 使用BlockingQuene模拟生产者与消费者 10 * 11 * @author Ymmmsick 12 * 13 */ 14 public class BlockingQueneTest { 15 16 public static void main(String[] args) { 17 BlockingQueue<String> quene = new LinkedBlockingDeque<String>(2); 18 ExecutorService es = Executors.newCachedThreadPool(); 19 for (int i = 0; i < 10; i++) { 20 es.execute(new Product(quene, "Thread->" + i)); 21 es.execute(new Consumer(quene)); 22 } 23 24 es.shutdown(); 25 } 26 } 27 28 class Product implements Runnable { 29 30 private BlockingQueue<String> quene; 31 private String name; 32 33 public Product(BlockingQueue<String> quene, String name) { 34 this.quene = quene; 35 this.name = name; 36 } 37 38 @Override 39 public void run() { 40 // TODO Auto-generated method stub 41 try { 42 quene.put(name); 43 System.out.println("Product :" + name); 44 } catch (InterruptedException e) { 45 // TODO Auto-generated catch block 46 e.printStackTrace(); 47 } 48 } 49 50 } 51 52 class Consumer implements Runnable { 53 54 private BlockingQueue<String> quene; 55 56 public Consumer(BlockingQueue<String> quene) { 57 this.quene = quene; 58 } 59 60 @Override 61 public void run() { 62 // TODO Auto-generated method stub 63 try { 64 String t = quene.take(); 65 System.out.println("Consumer:" + t); 66 } catch (InterruptedException e) { 67 // TODO Auto-generated catch block 68 e.printStackTrace(); 69 } 70 } 71 72 }
输出结果:
Product :Thread->0
Consumer:Thread->0
Product :Thread->1
Product :Thread->2
Consumer:Thread->1
Consumer:Thread->2
Product :Thread->3
Consumer:Thread->3
Product :Thread->4
Consumer:Thread->4
Product :Thread->5
Consumer:Thread->5
Product :Thread->6
Consumer:Thread->6
Product :Thread->7
Consumer:Thread->7
Product :Thread->8
Consumer:Thread->8
Product :Thread->9
Consumer:Thread->9
结论:LinkedBlockingQuene在同一时间段内最多只能保持两个对象在队列,对象溢满的时候生产者会等待阻塞,对象空置的时候消费者会等待阻塞。