Producer/Consumer threads using a Queue

前端 未结 7 1705
抹茶落季
抹茶落季 2020-11-22 17:00

I\'d like to create some sort of Producer/Consumer threading app. But I\'m not sure what the best way to implement a queue between the two.

So I\'ve so

相关标签:
7条回答
  • 2020-11-22 18:04

    I have extended cletus proposed answer to working code example.

    1. One ExecutorService (pes) accepts Producer tasks.
    2. One ExecutorService (ces) accepts Consumer tasks.
    3. Both Producer and Consumer shares BlockingQueue.
    4. Multiple Producer tasks generates different numbers.
    5. Any of Consumer tasks can consume number generated by Producer

    Code:

    import java.util.concurrent.*;
    
    public class ProducerConsumerWithES {
        public static void main(String args[]){
             BlockingQueue<Integer> sharedQueue = new LinkedBlockingQueue<Integer>();
    
             ExecutorService pes = Executors.newFixedThreadPool(2);
             ExecutorService ces = Executors.newFixedThreadPool(2);
    
             pes.submit(new Producer(sharedQueue,1));
             pes.submit(new Producer(sharedQueue,2));
             ces.submit(new Consumer(sharedQueue,1));
             ces.submit(new Consumer(sharedQueue,2));
             // shutdown should happen somewhere along with awaitTermination
             / * https://stackoverflow.com/questions/36644043/how-to-properly-shutdown-java-executorservice/36644320#36644320 */
             pes.shutdown();
             ces.shutdown();
        }
    }
    class Producer implements Runnable {
        private final BlockingQueue<Integer> sharedQueue;
        private int threadNo;
        public Producer(BlockingQueue<Integer> sharedQueue,int threadNo) {
            this.threadNo = threadNo;
            this.sharedQueue = sharedQueue;
        }
        @Override
        public void run() {
            for(int i=1; i<= 5; i++){
                try {
                    int number = i+(10*threadNo);
                    System.out.println("Produced:" + number + ":by thread:"+ threadNo);
                    sharedQueue.put(number);
                } catch (Exception err) {
                    err.printStackTrace();
                }
            }
        }
    }
    
    class Consumer implements Runnable{
        private final BlockingQueue<Integer> sharedQueue;
        private int threadNo;
        public Consumer (BlockingQueue<Integer> sharedQueue,int threadNo) {
            this.sharedQueue = sharedQueue;
            this.threadNo = threadNo;
        }
        @Override
        public void run() {
            while(true){
                try {
                    int num = sharedQueue.take();
                    System.out.println("Consumed: "+ num + ":by thread:"+threadNo);
                } catch (Exception err) {
                   err.printStackTrace();
                }
            }
        }   
    }
    

    output:

    Produced:11:by thread:1
    Produced:21:by thread:2
    Produced:22:by thread:2
    Consumed: 11:by thread:1
    Produced:12:by thread:1
    Consumed: 22:by thread:1
    Consumed: 21:by thread:2
    Produced:23:by thread:2
    Consumed: 12:by thread:1
    Produced:13:by thread:1
    Consumed: 23:by thread:2
    Produced:24:by thread:2
    Consumed: 13:by thread:1
    Produced:14:by thread:1
    Consumed: 24:by thread:2
    Produced:25:by thread:2
    Consumed: 14:by thread:1
    Produced:15:by thread:1
    Consumed: 25:by thread:2
    Consumed: 15:by thread:1
    

    Note. If you don't need multiple Producers and Consumers, keep single Producer and Consumer. I have added multiple Producers and Consumers to showcase capabilities of BlockingQueue among multiple Producers and Consumers.

    0 讨论(0)
提交回复
热议问题