import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 第7课正文第六节的完整示例：有界队列 + 结束标记的生产者—消费者。
 * 运行：java reference/ProducerConsumerExample.java（Java 17 或 21）。
 * 预期输出：处理 0 到处理 5 依次各一行，最后一行“消费者结束”。
 */
public class ProducerConsumerExample {
    public static void main(String[] args) throws Exception {
        BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(2);   // 有界：最多等待 2 个
        final int END = -1;                                            // 结束标记（poison object）

        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 6; i++) {
                    queue.put(i);                                      // 队满时在这里等
                }
                queue.put(END);                                        // 最后放结束标记
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();                    // 恢复中断标记再退出
            }
        });

        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    int x = queue.take();                              // 队空时在这里等
                    if (x == END) {
                        break;                                         // 取到结束标记就退出
                    }
                    System.out.println("处理 " + x);
                }
                System.out.println("消费者结束");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        producer.start();
        consumer.start();
        producer.join(5000);
        consumer.join(5000);
        if (producer.isAlive() || consumer.isAlive()) {
            throw new AssertionError("生产者或消费者没有按时结束");
        }
    }
}
