MST

星途 面试题库

面试题:Java并发编程中生产者 - 消费者模式在Java中的实现

请描述Java并发编程中生产者 - 消费者模式的概念,并使用Java代码实现一个简单的生产者 - 消费者模型,要求使用`BlockingQueue`。
14.1万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

生产者 - 消费者模式概念

生产者 - 消费者模式是一种经典的多线程设计模式。在该模式中,生产者负责生成数据并将其放入缓冲区,消费者则从缓冲区中取出数据进行处理。这种模式通过缓冲区解耦了生产者和消费者的操作,使得它们可以独立地运行,提高了系统的并发性能和可维护性。

Java代码实现

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

class Producer implements Runnable {
    private final BlockingQueue<Integer> queue;

    public Producer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                queue.put(i);
                System.out.println("Produced: " + i);
                Thread.sleep(100);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

class Consumer implements Runnable {
    private final BlockingQueue<Integer> queue;

    public Consumer(BlockingQueue<Integer> queue) {
        this.queue = queue;
    }

    @Override
    public void run() {
        try {
            while (true) {
                Integer item = queue.take();
                System.out.println("Consumed: " + item);
                Thread.sleep(200);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

public class ProducerConsumerExample {
    public static void main(String[] args) {
        BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(5);
        Thread producerThread = new Thread(new Producer(queue));
        Thread consumerThread = new Thread(new Consumer(queue));

        producerThread.start();
        consumerThread.start();

        try {
            producerThread.join();
            consumerThread.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

在上述代码中:

  1. Producer类实现了Runnable接口,在run方法中不断生成数据并使用BlockingQueueput方法将数据放入队列。如果队列已满,put方法会阻塞直到队列有空间。
  2. Consumer类同样实现了Runnable接口,在run方法中使用BlockingQueuetake方法从队列中取出数据。如果队列为空,take方法会阻塞直到队列有数据。
  3. ProducerConsumerExample类的main方法中,创建了一个容量为5的LinkedBlockingQueue,并启动了生产者线程和消费者线程。