生产者和消费者共享队列,其值来自HttpRequest

时间:2015-09-02 03:38:48

标签: java multithreading spring producer-consumer

这是制作人/消费者的经典问题。我在启动Spring Boot应用程序时启动了两个线程。我只想在收到httpRequest时从Producer线程写入共享队列。那么,我怎样才能将这个值传递给我的Producer线程,以便我可以把它放在共享队列中?有可能吗?

主要类

public class ProducerConsumerPattern {
    public static void main(String args[]) {

        // create shared object
        BlockingQueue sharedQueue = new LinkedBlockingQueue();

        // create Producer and Consumer Thread
        Thread prodThread = new Thread(new Producer(sharedQueue));
        Thread consThread = new Thread(new Consumer(sharedQueue));

        // start producer and Consumer thread
        prodThread.start();
        consThread.start();
    }
}

消费者类

class Consumer implements Runnable {
    private final BlockingQueue sharedQueue;

    public Consumer (BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    }

    @Override
    public void run() {
        while(true) {
            try {
                System.out.println("Consumed: "+ sharedQueue.take());
            } catch (InterruptedException ex) {
                Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

制作人类

class Producer implements Runnable {
    private final BlockingQueue sharedQueue;

    public Producer(BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    }

    @Override
    public void run() {
        // I don't want to write in the queue the counter values.
        // I want to put my own values, when I receive them from outside **
        for (int i=0; i<10; i++) {
            try {
                System.out.println("Produced: " + i);
                sharedQueue.put(i);
            } catch (InterruptedException ex) {
                Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

我可以通过@RestController@RequestMapping获取http参数,但是如何获取Producer线程并将此新值放入队列?

提前致谢!

1 个答案:

答案 0 :(得分:3)

你需要得到生产者的句柄来推动任何项目排队。在生产者中写一个方法来推送项目:

public class Producer implements Runnable {
    private final BlockingQueue sharedQueue;

    public Producer(BlockingQueue sharedQueue) {
        this.sharedQueue = sharedQueue;
    }

    public void pushItem(int item) throws InterruptedException {
        System.out.println("Produced: " + item);
        sharedQueue.put(item);
    }

    @Override
    public void run() {
        //I don't want to write in the queue the counter values. I want to put my own values, when I receive them from outside **
        for(int i=0; i<10; i++){
            try {
                System.out.println("Produced: " + i);
                sharedQueue.put(i);
            } catch (InterruptedException ex) {
                //Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
}

现在在main方法中你需要写:

public static void main(String[] args) throws InterruptedException {
        //Creating shared object
        BlockingQueue sharedQueue = new LinkedBlockingQueue();

        //Creating Producer and Consumer Thread
        Producer producer = new Producer(sharedQueue);
        Thread prodThread = new Thread(producer);
        Thread consThread = new Thread(new Consumer(sharedQueue));

        //Starting producer and Consumer thread
        prodThread.start();
        consThread.start();

        producer.pushItem(2000);
    }

项目2000将由主线程推送但订单无法保证。样本运行的输出是:

Produced: 0 Produced: 2000 Produced: 1 Produced: 2 Produced: 3 Consumed: 0 Produced: 4 Consumed: 2000 Produced: 5 Produced: 6 Consumed: 1 Produced: 7 Consumed: 2 Produced: 8 Produced: 9 Consumed: 3 Consumed: 4 Consumed: 5 Consumed: 6 Consumed: 7 Consumed: 8 Consumed: 9