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 Ymmmsick12 *13 */14 public class BlockingQueneTest {15 16 public static void main(String[] args) {17 BlockingQueuequene = new LinkedBlockingDeque (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 quene;31 private String name;32 33 public Product(BlockingQueue quene, String name) {34 this.quene = quene;35 this.name = name;36 }37 38 @Override39 public void run() {40 // TODO Auto-generated method stub41 try {42 quene.put(name);43 System.out.println("Product :" + name);44 } catch (InterruptedException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 }48 }49 50 }51 52 class Consumer implements Runnable {53 54 private BlockingQueue quene;55 56 public Consumer(BlockingQueue quene) {57 this.quene = quene;58 }59 60 @Override61 public void run() {62 // TODO Auto-generated method stub63 try {64 String t = quene.take();65 System.out.println("Consumer:" + t);66 } catch (InterruptedException e) {67 // TODO Auto-generated catch block68 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在同一时间段内最多只能保持两个对象在队列,对象溢满的时候生产者会等待阻塞,对象空置的时候消费者会等待阻塞。