【问题标题】:Producer and Consumer shared queue with values coming from HttpRequest生产者和消费者共享队列,其值来自 HttpRequest
【发布时间】:2015-11-27 10:30:05
【问题描述】:

这是生产者/消费者的经典问题。当我引导我的 Spring Boot 应用程序时,我启动了两个线程。我只想在收到 httpRequest 时从 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线程并将这个新值放入队列?

提前致谢!

【问题讨论】:

    标签: java multithreading spring producer-consumer


    【解决方案1】:

    您需要获取生产者的句柄才能将任何项目推入队列。在生产者中编写一个方法来推送项目:

    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

    【讨论】:

    • 感谢您的回答。但是当我引导我的 Spring Boot 应用程序时,我会执行该代码并启动线程。那个时候我不想推这个项目。我想异步推送新项目,当我使用@restcontroller 从我的任何端点获得httprequest 时,一旦线程已经运行。对不起,如果我不够清楚
    • @jamlet:您需要获取生产者的句柄,然后您可以随时随地调用方法pushItem。我刚刚在这里展示了一个例子。您也可以将生产者的引用传递给其他方法。
    • 老实说,我不知道如何处理那里的制作人。另一个问题是,在生产者的 run 方法中,因为我不想在那里做任何事情,所以我就离开它:while(true){ }?
    猜你喜欢
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2020-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多