给定一个(ArrayList)将其改写成一个简单的阻塞队列,要求拥有put和get方法,以及getSize方法,能够支持多个生产者和多个消费者线程拥塞调用。
1】使用synchronized锁或ReentrantLock锁实现
1】使用Object的wait、notify、notifyAll来实现
基本思路:使用put方法向容器中添加元素,使用get方法从容器中取出元素,在使用put方法添加元素的时候进行判断,如果容器已经满了,此时调用wait()方法,使用添加线程阻塞,等待消费线程取出元素,腾出容器空间后才能再向其中添加元素,同理当使用get方法获取元素的时候,如果容器已经为空,此时要调用wait()方法,使得取出元素线程阻塞,等待添加线程添加元素,容器不为空时才能再从容器中取出元素
public class MyArrayBlockingQueue<T>{
/*
* 调用无参构造方法,阻塞队列的默认长度
*/
public static final int SIZE_VALUE=10;
/*
* 队列的容器存放队列的元素
*/
public final List<T> lists=new ArrayList<>();
/*
* 队列的最大容量
*/
private final int maxSize;
/*
* 队列当前元素个数
*/
private int size=0;
public MyArrayBlockingQueue() {
super();
this.maxSize=SIZE_VALUE;
}
/**
* 带参构造方法,创建时可设定队列最大元素
* @param maxSize 队列最大元素数量
*/
public MyArrayBlockingQueue(int maxSize) {
this.maxSize = maxSize;
}
/**
* 生产者向容器中插入元素时调用的方法
* @param t 传入队列中的元素
* @throws InterruptedException 向上抛出线程中断的异常
*/
public synchronized void put(T t) throws InterruptedException {
while (lists.size()==maxSize) {
System.out.println("队列中元素数量为"+maxSize+"个,队列进入则阻塞状态");
this.wait();
}
lists.add(t);
++size;
System.out.println("生产元素中元素数量size:"+size+" ");
this.notifyAll();//唤醒消费线程进行消费
}
/**
* 消费者从容器中取元素时调用的方法
*/
public synchronized T get() {
T t=null;
while(lists.size()==0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
t=lists.get(0);
lists.remove(0);
--size;
System.out.println("消费容器中元素数量为size:"+size+" ");
this.notifyAll();//唤醒生产线程进行生产
return t;
}
/**
* 队列当前元素数量
*/
public int getSize() {
return size;
}
}
测试结果:

第一次测试,发现取出的数据都是0;后来检查了一下,是在get方法中,忘记将取出的元素remove掉了,导致取到的值都是0,有点粗心了;
使用其他的集合累的话,也可以转换成阻塞队列,大家也可以试一试
来源:https://www.cnblogs.com/SpaceKiller/p/12536109.html