我有一个使用Spring框架的java应用程序。我的应用程序由多个生产者和消费者组成。
我在生产者和消费者之间宣布一个共享队列,如下所示:
<bean id="theQueue" class="java.util.concurrent.LinkedBlockingQueue"/>
此队列将传递给producer构造函数和消费者构造函数,如下所示。
<bean id="Consumer" class="com.app.Consumer">
<constructor-arg ref="theQueue"/>
</bean>
<bean id="Producer1" class="com.app.Producer">
<constructor-arg ref="theQueue"/>
</bean>
<bean id="Producer2" class="com.app.producer">
<constructor-arg ref="theQueue"/>
</bean>
<bean id="Producer3" class="com.app.producer">
<constructor-arg ref="theQueue"/>
</bean>
构造函数如下所示:
package com.app.producer;
public class Producer implements Runnable {
private final Queue<Message> queue;
public Producer (Queue<Message> queue) {
this.queue = queue;
}
...
public void run() {
while (someCondition) {
...
this.queue.add(Message);
...
}
}
}
package com.app.Consumer;
public class Consumer implements Runnable {
private final BlockingQueue<Message> queue;
public Consumer(BlockingQueue<Message> queue) {
this.queue = queue;
}
...
public void run() {
while (true) {
...
Message message = this.queue.take();
...
}
}
}
应用程序正确启动但在一段时间后,生产者将元素添加到队列但消费者仍在队列中等待。似乎生产者在将元素插入队列时没有唤醒消费者。但是,如果我将队列类型从PriorityBlockingQueue更改为BlockingQueue,则可以使用,即替换:
private final PriorityBlockingQueue<Message> queue;
通过
private final BlockingQueue<Message> queue;
消息实现可比较如下:
public class Message implements Comparable<Message> {
public enum Priority{
NORMAL,
HIGH,
URGENT
}
private final String msg;
private final Priority priority;
public Message(String msg, Priority priority) {
this.msg = msg;
this.priority = priority;
}
...
public int compareTo(Message compareMessage) {
int retVal = (int) (compareMessage.priority.ordinal() - this.priority.ordinal());
return retVal;
}
}
为什么PriorityBlockingQueue的行为不符合预期?我不明白为什么如果生产者刚刚将它们添加到队列中,那么消费者仍在等待队列中的元素准备就绪。