package ProducerConsumerExample;
import java.util.*;

class Buffer {
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity;

    public Buffer(int capacity) {
        this.capacity = capacity;
    }

    public synchronized void produce(int value) throws InterruptedException {
        while (queue.size() == capacity) {
            System.out.println("버퍼가 가득 차서 생산자가 기다립니다...");
            wait();
        }
        queue.add(value);
        System.out.println("생산되었음: " + value);
        notify();
    }

    public synchronized int consume() throws InterruptedException {
        while (queue.isEmpty()) {
            System.out.println("버퍼가 비어서 소비자가 기다립니다...");
            wait();
        }
        int value = queue.poll();
        System.out.println("소비되었음: " + value);
        notify();
        return value;
    }
}

class Producer extends Thread {
    private final Buffer buffer;
    public Producer(Buffer buffer) { this.buffer = buffer; }

    @Override
    public void run() {
        try {
            int value = 0;
            while (true) {
                buffer.produce(value++);
                Thread.sleep(500);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Consumer extends Thread {
    private final Buffer buffer;
    public Consumer(Buffer buffer) { this.buffer = buffer; }

    @Override
    public void run() {
        try {
            while (true) {
                buffer.consume();
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class ProducerConsumerExample {
    public static void main(String[] args) {
        Buffer buffer = new Buffer(5);
        Producer producer = new Producer(buffer);
        Consumer consumer = new Consumer(buffer);
        
        producer.start();
        consumer.start();
    }
}
