Search code examples
javamultithreadingspringproducer-consumer

Producer and Consumer shared queue with values coming from HttpRequest


This is the classic problem of Producer/Consumer. I start both threads when I bootstrap my Spring Boot application. I just want to write from Producer thread into the shared queue when I receive a httpRequest. So, how can I pass this value to my Producer thread in order that I can put it in the shared queue?. Is it possible?

Main Class

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();
    }
}

Consumer Class

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);
            }
        }
    }
}

Producer Class

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);
            }
        }
    }
}

I can get the http param through @RestController and @RequestMapping, but how can I get Producer thread and put this new value into the queue?

Thanks in advance!


Solution

  • You need to get handle of producer for pushing any item to queue. Write a method in producer to push item:

    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);
                }
            }
        }
    }
    

    Now in main method you need to write:

    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);
        }
    

    The item 2000 will be pushed by main thread but the order is not guaranteed. The output for a sample run is:

    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