我正在处理生产者/消费者模式,我的生产者应该等待可能是结果对象或异常的答案。 这样做的最佳方法是什么? 我阅读了很多关于这种模式的例子,但每次制作人都不会介意返回值或消费者例外。
public class BlockingQueueExample {
public static void main(String[] args) throws Exception {
BlockingQueue queue = new ArrayBlockingQueue(1024);
Producer producer = new Producer(queue);
Consumer consumer = new Consumer(queue);
new Thread(producer).start();
new Thread(consumer).start();
Thread.sleep(4000);
}
}
public class Producer implements Runnable{
protected BlockingQueue queue = null;
public Producer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
try {
queue.put(new Job("test"));
//here I need the job result or exception
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Consumer implements Runnable{
protected BlockingQueue queue = null;
public Consumer(BlockingQueue queue) {
this.queue = queue;
}
public void run() {
while(true){
queue.take();
try{
// ... my job
Result obj;
// I have to return to producer the result!
}catch(Exception e){
//In case of exception I have to return the exception to the producer.
}
}
}
}
我现在唯一的选择是使用带有此对象的队列:
public class Job{
private String input;
private Exception exception;
private String result;
public Jon(String input){
this.input=input;
this.exception=null;
}
public void setException(Exception exception){
this.exception=exception;
}
public Exception getException(){
return this.exception;
}
public void setResult(String result){
this.result=result;
}
public Exception getResult(){
return this.result;
}
}
让procuder回读其结果或异常。 否则我应该使用FutureTask的BlockingQueue吗?
答案 0 :(得分:0)
首先,帮自己一个忙,开始使用泛型。这不应该是BlockingQueue
,应该是BlockingQueue<Job>
。这个。是。 2015。
其次,你需要两个队列。一个队列用于为您的消费者提供输入,另一个队列用于从他们那里收集输出。因此,您可以使用BlockingQueue<String>
作为输入队列,并且可以将Job
重命名为Result
并为输出队列设置BlockingQueue<Result>
。
当然,当您的生产者被阻止等待从输入队列中读取结果时,您无法将内容添加到输出队列,因此您需要为生产者设计不同的设计。但这并不比你现在所处的情况更糟糕,在那里你(错误地)期望把一份工作放在一个队列中,并以某种方式(神奇地?)在同一循环中收到结果。
答案 1 :(得分:0)
您应该将作业排队与结果获取分开。为了实现这一点,您可以创建一个队列并从使用者线程向其添加结果。因此,您将需要一个负责结果处理的消费者。