? 作者:小胡_不糊涂
🌱 作者主页:小胡_不糊涂的个人主页
📀 收录专栏:JavaEE
💖 持续更文,关注博主少走弯路,谢谢大家支持 💖
阻塞队列是?种特殊的队列,遵守 “先进先出” 的原则。
阻塞队列能是?种线程安全的数据结构,并且具有以下特性:
阻塞队列的?个典型应?场景就是 “?产者消费者模型”。这是?种?常典型的开发模型。
生产者消费模型:
?产者消费者模式就是通过?个容器来解决?产者和消费者的强耦合问题。
?产者和消费者彼此之间不直接通讯,?通过阻塞队列来进?通讯,所以?产者?产完数据之后不?等待消费者处理,直接扔给阻塞队列,消费者不找?产者要数据,?是直接从阻塞队列?取
在 Java 标准库中内置了阻塞队列。如果我们需要在?些程序中使?阻塞队列,直接使?标准库中的即可。
示例:
public static void main(String[] args) throws InterruptedException {
BlockingQueue<String> queue=new ArrayBlockingQueue<>(100);
queue.put("aaa");//入队列--有阻塞功能的
String elem=queue.take();//出队
System.out.println(elem);//aaa
}
方法:
- 先实现普通队列–使用数组实现循环队列,保证实现出入队列的操作
- 加上线程安全–synchronized
- 加上阻塞队列
//模拟实现
class MyBlockingQueue{
private String[] elems=null;//数组实现队列
private int head=0;//队首
private int tail=0;//队尾
private int size=0;//元素个数
private Object loker=new Object();//锁对象
public MyBlockingQueue(int capacity){
elems=new String[capacity];
}
//入队列
public void put(String elem) throws InterruptedException {
//有读写操作的
synchronized (loker) {
//队列满了,进入阻塞
while(size >= elem.length()) {
loker.wait();
}
elems[tail] = elem;//新元素放入tail位置上
tail++;
//tail=tail%elems.length;
if (tail >= elems.length) {
tail = 0;//循环对列
}
size++;
//当队列为空,只要有元素入队列就唤醒下面的wait
loker.notify();
}
}
//出队列
public String take() throws InterruptedException {
String tmp =null;
synchronized (loker) {
//队列为空
while(size == 0) {
loker.wait();
}
tmp = elems[head];
head++;
if (head >= elems.length) {
head = 0;
}
size--;
//当队列满了,只要有元素出队列就唤醒前面的入队列
loker.notify();
}
return tmp;
}
}