自定义阻塞队列

思路

  1. 定义一个数组Object[] items,用于存放元素,定义一个变量count,记录当前元素个数;
  2. 定义一个独占锁,只有持有锁才能进行操作;
  3. 定义两个条件变量,当元素满的时候,通知生产者等待,当元素为空的时候,通知消费者等待;
  4. 判断元素满,count == items.length;判断元素空,count==0;
  5. 生产元素时,需要记录元素要存放的下标,定义putIndex;消费元素时,需要记录元素要取走的下标,定义takeIndex;
  6. 定义生产元素的方法put,此时唤醒消费者;定时消费元素的方法,此时唤醒生产者;

编码如下

public class MyArrayBlockingQueue<E> {
	private Object[] items;
	private int count;
	private ReentrantLock lock;
	private int takeIndex;
	private int putIndex;
	private Condition notFull;
	private Condition notEmpty;
	public MyArrayBlockingQueue(int capacity) {
		if (capacity <=0) {
			throw new IllegalArgumentException();
		}
		items = new Object[capacity];
		notFull = lock.newCondition();
		notEmpty = lock.newCondition();
	}
	
	public void put(E e) {
		try {
			lock.lock();
			while (count == items.length) {
				notFull.await();
			}
			items[putIndex++] = e;
			if (putIndex == items.length) {
				putIndex = 0;
			}
			count++;
			notEmpty.signal();
		} catch (InterruptedException e1) {
			e1.printStackTrace();
		} finally {
			lock.unlock();
		}
	}
	
	public E take() throws InterruptedException {
		try {
			lock.lock();
			while (count == 0) {
				notEmpty.await();
			}
			@SuppressWarnings("unchecked")
			E e = (E) items[takeIndex];
			items[takeIndex] = null;
			takeIndex++;
			if (takeIndex == items.length) {
				takeIndex = 0;
			}
			count--;
			notFull.signal();
			return e;
		} finally {
			lock.unlock();
		}
	}
}
posted @ 2021-07-08 10:45  咸与维新  阅读(80)  评论(0)    收藏  举报