1)设计一个队列由数组实现,已知元素为 private Object[] items 请补充完整?
2)如果要实现一个有界阻塞队列,需要定义什么元素?
3)实现有界阻塞队列的offer方法?
解答
1)有界队列或无界队列
无界队列:很好实现但是会导致head前的数组空间无法利用,容易造成内存溢出。
int head ;//表示元素出队时的索引
int tail; //表示元素入队时的索引
初始head=tail=0;当head==tail时队列为空
元素入队时 :items[tail++]=e;
元素出队时: items[head++]=null;
有界队列:
int n;//队列容量 需要在队列创建时指定
int head;//出队索引标记
int tail; //入队索引标记
添加元素时 : items[tail]=e; 若 tail==n tail=0;
元素出队时: items[head]=e;若 head==n head=0;
当元素出队不及时会造成元素丢失,当元素生产不及时会造成消费空数据。
可以添加 int size ; //元素容量 当size==n的时候禁止入队操作,等size==0时禁止出队操作
入队:size<n ;items[tail]=e; size++ ;tail=tail++%n ;return true;
size==n return false
出队 size!=0 item[head]=null ; size-- ;head=head++%n ;return true
size=0 return false;
2)上题我们已经实现了有界队列,那么如何实现有界阻塞队列呢?
阻塞队列实现与生产者消费者挂钩,可以把入队操作当作生产者生产消息,出队操作当作消费者消费消息。当队列非空的时候消费者可以消费消息,队列非满的时候生产者可以生产消息,为了保证消息的一致性和准确性可以使用锁来实现消息生产可消费的安全性。
数据结构定义:
object [] items//存放元素
private int n;//容量
ReentrantLock lock //锁,保证线程安全
private final Condition notEmpty;//实现消费者线程的等待和唤醒
private final Condition notFull;//实现生产者线程的等待和唤醒
private int account ;//元素数目
private int takeIndex ;//记录要出队的索引位置
private int putIndex ;//记录要入队的索引位置
3)offer方法 ,有两种非阻塞式入队和阻塞式入队
阻塞式入队
private void offer(E e){
checkEisNull(e);//元素非空
ReentrantLock lock =this.lock;
lock.lock();
try{
while(account==items.length) //队列已满
{
notFull.wait();
}
Inqueue(e);
}finally{
lock.unlock();
}
}
非阻塞式
private void offer(E e){
checkEisNull(e);//元素非空
ReentrantLock lock =this.lock;
lock.lock();
try{
if(account==items.length) //队列已满
{ return false; }
Inqueue(e);
return true;
}finally{ lock.unlock();
}
}