队列可以使用数组或链表进行实现,这里使用数组模拟队列
队列有一个最大容量 maxSize,并且有两个变量 front 和 rear 分别用来记录队列前后端的下标
public class BlockingQueueDemo {
public static void main(String[] args) {
BlockingQueue blockingQueue = new BlockingQueue(1000);new Thread(()->{
for (int i = 1; i <= 100; i++) {
try {
blockingQueue.put(i);Thread.sleep((long)Math.random() * 10);} catch (InterruptedException e) {
e.printStackTrace();}}}, "Thread1").start();new Thread(() -> {
while (true) {
try {
int take = blockingQueue.take();} catch (InterruptedException e) {
e.printStackTrace();}}}, "Thread--2").start();new Thread(() -> {
while (true) {
try {
int take = blockingQueue.take();} catch (InterruptedException e) {
e.printStackTrace();}}}, "Thread--3").start();}
}class BlockingQueue {
private int[] queue; // 存放数据,模拟队列private volatile int maxSize; // 最大容量private volatile int front; // 队列头部数据再向前一位位置private volatile int rear; // 指向队列尾部最后一个数据位置public BlockingQueue (int maxSize) {
this.maxSize = maxSize;queue = new int[maxSize];front = -1;rear = -1;}// 判断队列是否已满public boolean isFull() {
return rear == maxSize - 1;}// 判断队列是否为空public boolean isEmpty() {
return rear == front;}// 队列操作:入队列public synchronized void put(int value) throws InterruptedException {
// 队列满,阻塞while (isFull()) {
System.out.printf("队列满,%s正在等待\n", Thread.currentThread().getName());this.wait();}// 队列空,唤醒所有阻塞线程if (isEmpty()) {
notifyAll();}// 入队列rear++;queue[rear] = value;this.notify();System.out.printf("%s向队列中添加数据%d成功\n", Thread.currentThread().getName(), queue[rear]);}// 队列操作:出队列public synchronized int take() throws InterruptedException {
// 队列为空,阻塞while (isEmpty()) {
System.out.printf("队列空,%s正在等待~~~\n", Thread.currentThread().getName());this.wait();}if (isFull()) {
notifyAll();}front++;notify();System.out.printf("%s从队列中取出元素%d\n", Thread.currentThread().getName(), queue[front], queue.length);return queue[front];}
}