Java 具有BlockingQueue和返回值或异常的生产者/消费者模式

Java 具有BlockingQueue和返回值或异常的生产者/消费者模式,java,producer-consumer,Java,Producer Consumer,我正在处理生产者/消费者模式,生产者应该等待可能是结果对象或异常的答案。 最好的方法是什么? 我读过很多这种模式的例子,但每次制作人都不在乎返回值或消费者异常 public class BlockingQueueExample { public static void main(String[] args) throws Exception { BlockingQueue queue = new ArrayBlockingQueue(1024); Pr

我正在处理生产者/消费者模式,生产者应该等待可能是结果对象或异常的答案。 最好的方法是什么? 我读过很多这种模式的例子,但每次制作人都不在乎返回值或消费者异常

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;
    }
}
并让处理器读回其结果或异常。 否则我应该使用FutureTask的阻塞队列吗?

首先,帮你自己一个忙,开始使用泛型。这不应该是
阻塞队列
,而应该是
阻塞队列
。这是2015年

其次,您需要两个队列。一个队列用于向消费者提供输入,另一个队列用于从消费者收集输出。因此,您可以对输入队列使用
BlockingQueue
,可以将
Job
重命名为
Result
,并对输出队列使用
BlockingQueue


当然,当生产者被阻止等待从输入队列读取结果时,您不能向输出队列添加内容,因此您需要为生产者提供不同的设计。但这并不比您现在所处的情况更糟糕,您(错误地)希望将作业放入队列,然后以某种方式(神奇地?)将结果返回到同一个循环中。

您应该将作业队列与结果获取分离。为了实现这一点,您可以再创建一个队列,并从使用者线程向其添加结果。因此,您还需要一个负责结果处理的消费者。

我不理解这个问题。你现在做的似乎很好。您可能应该在出现异常时退出
生产者。你还想到了什么?再看看你的问题,我认为你这里没有生产者/消费者的问题。如果您想将结果返回给制作者,这实际上不是模式的一部分。你需要即兴创作一些东西。看看Swing的SwingWorker。我试着向你解释真实的情况。我有n个智能卡线程(一个用于智能卡),它们有一个等待一些作业的while循环。生产者应将其作业发送到第一个可用的智能卡线程。我以为阻塞队列就可以了。但很明显,制片人需要工作的结果或例外。我相信你的想法是错误的。制作人不应该期望得到结果。让消费者这样做。或者另一个消费者,如果设计不考虑前者。生产者/消费者的全部目的是划分工作,而不是让生产者尝试处理结果。我认为你应该补充更多细节,为什么你认为这个智能卡阅读器需要多线程。它是什么样的系统,为什么线程在这里有意义?这是一个web服务器,智能卡作业可能来自多个客户端,智能卡可能不止一个,在这种情况下,我希望确保客户端获得第一个可用的智能卡来执行其作业。我不知道这是否是生产者/消费者的模式。但除此之外这是什么?我使用泛型,这只是一个示例代码。我无法理解这两种队列解决方案。消费者线程和生产者线程可能不止一个,在这种情况下如何获得正确答案?您阻止等待输入队列中的
结果,一旦有了一个
结果,您就可以通过检查
结果的
输入
成员来确定它属于哪个输入。这就是为什么我不建议从
结果
类中删除
输入
字段的原因。