一、普通不阻塞队列
还记得队列我们如何实现吗?我们用的是循环队列的方式,回一下:
描述:开始tail和head指针都指向最开始位置,往里面添加元素tail++,出元素head++
初始状态:
put元素后状态
take元素后状态
代码描述
public class MyBlockingQueue1 {int size=0;//记录放了几个元素int tail=0,head=0;String []data=new String[3];public void put(String elem){if(size==data.length){//队列满了return;}data[tail++]=elem;if(tail==data.length){tail=0;}size++;}public String take(){String sum;if(size==0)return null;sum=data[head++];if(head==data.length)head=0;size--;return sum;}
}
二、阻塞循环队列
这个阻塞的意思,我来解释下,就相当于,包饺子的时候,擀皮的人是生产者,包饺子的人是消费者,生产者每生产一个饺子,消费者就这一包饺子,如果生产者速度很慢,包饺子人手里没有了饺子皮,就会阻塞,当然如果消费者有很多的饺子皮,生产者进入阻塞
public class MyBlockingQueue2 {int size=0;//记录放了几个元素int tail=0,head=0;String []data=new String[3];Object locker=new Object();public void put(String elem) throws InterruptedException {//生产者synchronized (locker){while(size==data.length){//while是防止被特殊唤醒//队列满了//return;locker.wait();}data[tail++]=elem;if(tail==data.length){tail=0;}size++;locker.notify();//用来唤醒take的wait}}//消费者public String take() throws InterruptedException {synchronized (locker){String sum;while (size==0)locker.wait();sum=data[head++];if(head==data.length)head=0;size--;locker.notify();//用来唤醒put中的waitreturn sum;}}
}
class Test{public static void main(String[] args) throws InterruptedException {MyBlockingQueue2 queue=new MyBlockingQueue2();//消费者Thread t1=new Thread(()->{while (true){try {String result=queue.take();System.out.println("消费者元素"+result);Thread.sleep(500);//让消费者慢点消费,很重要} catch (InterruptedException e) {throw new RuntimeException(e);}}});//生产者Thread t2=new Thread(()->{int num=1;while (true){try {queue.put(num+++"");System.out.println("生产者元素"+num);} catch (InterruptedException e) {throw new RuntimeException(e);}}});t1.start();t2.start();}
}