Write a Java program that correctly implements the producer – consumer problem using the concept of inter thread communication.

 import java.util.LinkedList;

import java.util.Queue;

import java.util.Random;


public class ProducerConsumerProblem {


    public static void main(String[] args) {

        // Create a shared resource (the buffer) with a maximum capacity

        final Buffer sharedBuffer = new Buffer(5);


        // Create producer and consumer threads

        Thread producerThread = new Thread(new Producer(sharedBuffer), "ProducerThread");

        Thread consumerThread = new Thread(new Consumer(sharedBuffer), "ConsumerThread");


        // Start both threads

        producerThread.start();

        consumerThread.start();

    }

}


// The shared buffer class manages the queue and synchronization

class Buffer {

    private final Queue<Integer> queue = new LinkedList<>();

    private final int capacity;


    public Buffer(int capacity) {

        this.capacity = capacity;

    }


    // Method for the producer to add items

    public synchronized void produce(int value) throws InterruptedException {

        // Wait while the buffer is full

        while (queue.size() == capacity) {

            System.out.println("Buffer is full. Producer waiting...");

            wait(); // Releases the lock and waits for a consumer to notify

        }


        // Add the item to the buffer

        queue.add(value);

        System.out.println("Producer produced: " + value + " | Current size: " + queue.size());


        // Notify waiting consumers that an item is available

        notifyAll(); 

    }


    // Method for the consumer to remove items

    public synchronized int consume() throws InterruptedException {

        // Wait while the buffer is empty

        while (queue.size() == 0) {

            System.out.println("Buffer is empty. Consumer waiting...");

            wait(); // Releases the lock and waits for a producer to notify

        }


        // Remove the item from the buffer

        int value = queue.poll();

        System.out.println("Consumer consumed: " + value + " | Current size: " + queue.size());


        // Notify waiting producers that space is available

        notifyAll();


        return value;

    }

}


// The Producer runnable task

class Producer implements Runnable {

    private final Buffer buffer;

    private final Random random = new Random();


    public Producer(Buffer buffer) {

        this.buffer = buffer;

    }


    @Override

    public void run() {

        for (int i = 0; i < 10; i++) { // Produce 10 items

            try {

                int value = random.nextInt(100);

                buffer.produce(value);

                Thread.sleep(random.nextInt(500)); // Simulate time taken to produce

            } catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            }

        }

    }

}


// The Consumer runnable task

class Consumer implements Runnable {

    private final Buffer buffer;

    private final Random random = new Random();


    public Consumer(Buffer buffer) {

        this.buffer = buffer;

    }


    @Override

    public void run() {

        for (int i = 0; i < 10; i++) { // Consume 10 items

            try {

                buffer.consume();

                Thread.sleep(random.nextInt(1000)); // Simulate time taken to consume

            } catch (InterruptedException e) {

                Thread.currentThread().interrupt();

            }

        }

    }

}



Comments