import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class TestBoundedQueue {
public static void main(String[] args) throws Exception {
BoundedQueue<String> stringTestBoundedQueue = new BoundedQueue<>(16);
FutureTask<String> callableFutureTask = new FutureTask<>(new Callable<String>() {
@Override
public String call() throws Exception {
Thread.sleep(100);
String removeStr = stringTestBoundedQueue.remove();
System.out.println("移除满队列的一个元素:" + removeStr);
return removeStr;
}
});
new Thread(callableFutureTask).start();
for (int i = 0; i <= 16; i++) {
System.out.println(i);
stringTestBoundedQueue.add(i + "");
}
System.out.println("--------主程序结束---------");
}
}
class BoundedQueue<T> {
//装载元素数组
private Object[] items;
//添加的下标,删除的下标和数组当前数量
private int addIndex, removeIndex, count;
private Lock lock = new ReentrantLock();
private Condition notEmpty = lock.newCondition();
private Condition notFull = lock.newCondition();
public BoundedQueue(int initQueueSize){
items = new Object[initQueueSize];
}
/**
* 添加元素,如果数组队列已满,调用添加的线程进入等待状态,直到有空余位置
* @param t 所要添加元素
* @throws Exception
*/
public void add(T t) throws Exception{
lock.lock();
try {
while (count == items.length) {
//插入时已经满了则添加线程进入等待状态
System.out.println("队列已满,阻塞调用add()线程。");
notFull.await();
}
items[addIndex] = t;
addIndex++;
if (addIndex == items.length)
addIndex = 0;
count++;
notEmpty.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
/**
* 数组为空时,调用删除的线程进入等待状态,只有有新元素供其返回使用
* @return 返回一个头元素
* @throws Exception
*/
public T remove() throws Exception{
Object removeElement = null;
lock.lock();
try {
while (count == 0) {
System.out.println("队列为空,阻塞调用remove()线程");
notEmpty.await();
}
removeElement = items[removeIndex];
removeIndex++;
if (removeIndex == items.length)
removeIndex = 0;
count--;
notFull.signal();
return (T)removeElement;
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
return (T)removeElement;
}
}