BlockingQueue的含义是阻塞队列
即在队列满的时候,入队列会阻塞
在队列空的时候,出队列会阻塞
特殊之处在于阻塞,所以我们就了解两个方法
put(Object obj):在队列满时阻塞,直到队列不满,或者线程中断
take():在队列为空时阻塞,直到队列插入新值,或者线程中断
分类:
ArrayBlockingQueue
实现是数组(构造参数必须传数组长度参数)
LinkedBlockingQueue
实现是链表(构造参数可不传值(其实是设置的,为Integer.MAX_VALUE))
PriorityBlockingQueue
和PriorityQueue一样,是有序的
DelayQueue
可以设置过期时间
SynchronousQueue
内部仅允许容纳一个元素。当一个线程插入一个元素后会被阻塞,除非这个元素被另一个线程消费
SynchronousQueue和ArrayBlockingQueue(1)是有区别的,SynchronousQueue的生产者,在消费者未消费时,一直在等待消费,直到消费结束,才去做接下来的后续操作,而ArrayBlockingQueue(1)是把生产的物品直接放到过渡中心,自己继续把后续任务完成,再去准备第二个物品,再去放置第二个物品时,告知过渡中心不空,所以阻塞。
BlockingQueue**用处:**一般用在生产者-消费者模式
**案例:**有家店实行前台后厨分离,后厨准备食物,前台拿了之后消费,中间过渡区域最多可放置20件物品
代码:
public class BlockingQueueTest {
static BlockingQueue queue = new ArrayBlockingQueue<Integer>(20);
static Random random = new Random();
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("前台开工了");
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(random.nextInt(300));
System.out.println("我看到现在总共有" + queue.size() + "食物,我拿走第" + queue.take() + "件");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("前台卖完了,下班");
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("后厨开工了");
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(random.nextInt(100) + 50);
System.out.println("我看到现在总共有" + queue.size() + "食物,我要添加第" + i + "件");
queue.put(i);
System.out.println("我看到现在总共有" + queue.size() + "食物,我添加完第" + i + "件");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("后厨食材用完了,下班");
}
}).start();
}
}