Search code examples
javamultithreadingsynchronizedsynchronousproducer-consumer

How to Write Java multithreading Code for alternative producer and consumer approach. It should have 3 producers (P1,P2,P3) and 1 consumer(C1)


Can I Get a definite approach for achieving this. I have used join and wait for the alternative producer and consumer execution. This question was asked in an interview. He did not like my solution. I have also suggested a loop inside a synchronized block for consuming / producing resources.

below is the expected output:

p1 c1 p3 c1 p2 c1 p2 c1 . . .


Solution

  • import java.util.concurrent.atomic.AtomicInteger;
    
    public class TestClient {
    
        public static void main(String[] args) {
    
            ProducerConsumerUtilClass pcuc=new ProducerConsumerUtilClass();
    
            Thread producer1= new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while(true) {
                        try {
                            Thread.sleep(1000);
                            pcuc.produce();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
    
                    }
    
                }
            });
    
    Thread producer2= new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while(true) {
                        try {
                            Thread.sleep(1000);
                            pcuc.produce();
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
    
                    }
    
                }
            });
    Thread producer3= new Thread(new Runnable() {
    
        @Override
        public void run() {
            while(true) {
                try {
                    Thread.sleep(1000);
                    pcuc.produce();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
            }
    
        }
    });
    
    
    Thread consumer1= new Thread(new Runnable() {
    
    @Override
    public void run() {
        while(true) {
            try {
                Thread.sleep(1000);
                pcuc.consume();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
        }
    
    }
    });
    
            producer1.start();
            producer2.start();
            producer3.start();
            consumer1.start();
    
    
    
        }
    
    }
    
     class ProducerConsumerUtilClass {
    
        Object obj= new Object();
        private volatile boolean  available;
        private AtomicInteger atomicInteger=null;
    
        public ProducerConsumerUtilClass() {
            this.available = false;;
            this.atomicInteger = new AtomicInteger(0);;
        }
    
        public void produce() {
            synchronized (obj) {
                    while(available) {
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                    System.out.println("Produce By "+Thread.currentThread().getName()+"Value "+atomicInteger.getAndIncrement());
                    this.available=true;
                    obj.notifyAll();
            }
    
        }   
    
        public void consume() {
            synchronized (obj) {
                    while(!available) {
                    try {
                        obj.wait();
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                    System.out.println("Consume By "+Thread.currentThread().getName()+"Value "+atomicInteger.getAndIncrement());
                    this.available=false;
                    obj.notifyAll();
            }
    
        }   
    
    
    }