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在同一时间段内最多只能保持两个对象在队列,对象溢满的时候生产者会等待阻塞,对象空置的时候消费者会等待阻塞。