使用双向链表实现阻塞队列,代码如下。
class MessageQueue<T>{
//链表
private LinkedList<T> list = new LinkedList<>();
//容量
private int num;
public MessageQueue(int num) {
this.num = num;
}
//获取消息 没有消息则阻塞
public T take(){
return take(0);
}
//获取消息 并设置超时时间
public T take(long timeout){
//获取当前时间
//检查队列是否为空
synchronized (list) {
while (list.isEmpty()){
try {
//记录开始等待时间
long begin = System.currentTimeMillis();
list.wait(timeout);
//如果超过等待时间,则抛出异常
if (System.currentTimeMillis()-begin>timeout&&timeout!=0) throw new RuntimeException("超时");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//从队列的头部获取消息返回
T message = list.removeFirst();
//如果队列容量已满,通知生产者线程存入
list.notifyAll();
return message;
}
}
//存入消息
public void put(T message){
synchronized (list){
//检查队列是否已满
while (list.size() == num){
try {
list.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
//添加到队列
list.addLast(message);
//通知消费者获取
list.notifyAll();
}
}
}