什么是阻塞队列
分为阻塞和队列两个词。
阻塞:
对于消费者,没有吃的需要等待成为阻塞。
对于生产者,放入管道中的食物满了,无法放入,成为阻塞。
队列:
先进先出的数据结构。
阻塞队列管道
ArrayBlockingQueue 底层是有界数组。
LinedBlockingQueue底层是链表,可以设置整数个上线的节点。
public class ThreadDemo {
public static void main(String[] args) {
/*
需求:利用阻塞队列完成生产者和消费者(等待唤醒机制)的代码
细节:
生产者和消费者必须使用同一个阻塞队列
*/
/*
创建一个阻塞队列对象(管道对象)
参数:
指定阻塞队列里面最多可以放几个对象
使用方法:通过创建对象的方式传递给cook和foodie
*/
ArrayBlockingQueue<String> queue=new ArrayBlockingQueue<>(1);
//创建线程的对象
cook cook=new cook(queue);
foodie foodie=new foodie(queue);
//开启线程
cook.start();
foodie.start();
}
}
public class foodie extends Thread{
private ArrayBlockingQueue<String> queue;
//创建对象的时候,通过构造方法对成员变量进行赋值
public foodie(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true){
//不断的从阻塞队列中获取面条
try {
String food = queue.take();//take方法中也有锁,如果数据是0拿不出来进入等待,如果有数据的话就会获取,逻辑结束后释放锁try...finally
System.out.println(food);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class cook extends Thread{
private ArrayBlockingQueue<String> queue;
//创建对象的时候,通过构造方法对成员变量进行赋值
public cook(ArrayBlockingQueue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
while (true){
//不断的面条放进队列中
try {
queue.put("面条");//在这个方法底层会自动创建锁,装满了就等待,如果没装满就往里面一直装,逻辑执行完毕后释放锁
System.out.println("厨师放了一碗面条");//这个打印语句是锁外面的,所以可能会被抢走执行权。 对于数据其实是没有影响的,只是看上去数据错乱
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}