class MyBlockingQueue {
//这里队列底层用数组实现
private int[] queue = new int[1000];
//创建size变量记录队列现有元素的数量
private int size = 0;
//创建队头指针
private int head = 0;
//创建队尾指针
private int tail = 0;
//创建锁对象
private Object locker = new Object();
//向队列中添加元素,通过加锁操作当队列为满时阻塞,队列不满时才能添加
public void put(int value) throws InterruptedException {
synchronized (locker) {
if (size == queue.length) {
locker.wait();
}
queue[tail] = value;
tail++;
//或者写成tail = tail % queue.length,但在运行性能上CPU执行条件跳转更容易一些,取模操作比较麻烦一些
if (tail >= queue.length) {
tail = 0;
}
size++;
//解除队列为空时等待添加元素的阻塞,解除的是take方法中的wait
locker.notify();
}
}
//出队列,当队列为空时阻塞等待,直到队列中添加了元素
public Integer take() throws InterruptedException {
synchronized (locker) {
if (size == 0) {
locker.wait();
}
int ret = queue[head];
head++;
//或者写成head = head % queue.length,但在运行性能上CPU执行条件跳转更容易一些,取模操作比较麻烦一些
if (head >= queue.length) {
head = 0;
}
size--;
//解除队列满时等待出队列的阻塞,此处解除的是put方法中的wait
locker.notify();
return ret;
}
}
}
public class Demo3 {
//创建一个阻塞队列,来起到生产者消费者模型中“削峰填谷”的效果
private static MyBlockingQueue queue = new MyBlockingQueue();
public static void main(String[] args) {
//实现一个简易的生产者消费者模型
Thread producer = new Thread(() -> {
int num = 0;
while (true) {
try {
queue.put(num);
System.out.println("生产了" + num);
num++;
//此处可以看出生产者慢时,消费者也会跟着生产者的生产速率消费
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producer.start();
Thread customer = new Thread(() -> {
while (true) {
try {
int num = queue.take();
System.out.println("消费了" + num);
//此处可以看出,当消费者慢时,当生产者生产了大量数据,消费者会按照自己的节奏消费,生产者随后也就会随着消费者的速率生产
//Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
customer.start();
}
}
Java实现简单的阻塞队列
最新推荐文章于 2024-03-06 16:13:41 发布