Java多线程:生产者消费者模式与等待唤醒机制实战解析

0 下载量 187 浏览量 更新于2024-09-01 收藏 81KB PDF 举报
"Java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解" 在Java多线程编程中,生产者-消费者模式是一种经典的线程间通信方式,它描述了两个不同类型的线程——生产者线程和消费者线程如何协作处理共享资源。生产者负责生成数据,而消费者负责消费这些数据。在这个过程中,为了保证数据的一致性和避免线程间的竞态条件,需要使用同步机制。 在Java中,同步可以通过`synchronized`关键字实现。当一个方法被`synchronized`修饰时,它会获取到对象的监视器锁,确保同一时间只有一个线程可以执行该方法。在生产者-消费者模式中,生产者和消费者都会对共享资源(如队列)进行操作,因此需要使用同步来控制对资源的访问。 下面是一个简单的生产者-消费者模型的实现: 1. 首先,定义一个资源类`Resource`,包含资源名称和编号,以及生产资源和消费资源的方法。生产方法会增加资源编号并打印信息,消费方法则只是打印信息。 ```java class Resource { private String productName; private int count = 1; public void produce(String name) { this.productName = name + count; count++; System.out.println(Thread.currentThread().getName() + "生产者.." + this.productName); } public void consume() { System.out.println(Thread.currentThread().getName() + "消费者.." + this.productName); } } ``` 2. 接下来,创建生产者类`Producer`和消费者类`Consumer`,它们都实现`Runnable`接口,以便可以作为线程运行。 ```java class Producer implements Runnable { private Resource res; public Producer(Resource res) { this.res = res; } @Override public void run() { // 生产逻辑 } } class Consumer implements Runnable { private Resource res; public Consumer(Resource res) { this.res = res; } @Override public void run() { // 消费逻辑 } } ``` 3. 在主程序中,可以创建资源对象、生产者线程和消费者线程,并启动它们。为了实现生产者-消费者的协作,通常会使用阻塞队列,如`BlockingQueue`,它内置了同步机制,可以避免生产者过快生成数据导致消费者来不及消费,或者消费者过快消费导致生产者无数据可生产的情况。 ```java import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class Main { public static void main(String[] args) { BlockingQueue<Resource> queue = new LinkedBlockingQueue<>(10); // 创建容量为10的阻塞队列 Thread producerThread = new Thread(new Producer(queue), "Producer"); Thread consumerThread = new Thread(new Consumer(queue), "Consumer"); producerThread.start(); consumerThread.start(); try { producerThread.join(); consumerThread.join(); } catch (InterruptedException e) { e.printStackTrace(); } } } ``` 在生产者线程的`run()`方法中,生产者将资源放入队列;在消费者线程的`run()`方法中,消费者从队列中取出资源并消费。`BlockingQueue`的`put()`和`take()`方法会自动实现阻塞,当队列满时,生产者会被阻塞直到有空间;当队列空时,消费者会被阻塞直到有可用资源。 此外,Java提供了`wait()`和`notify()`方法来实现更精细的等待唤醒机制。生产者在队列满时调用`wait()`让出CPU,消费者在队列空时调用`wait()`。当生产者发现队列有空间或消费者发现队列有资源时,它们可以调用`notify()`唤醒等待的线程。不过,这种方式需要在同步块(`synchronized`关键字)中使用,以确保线程安全。 Java的生产者-消费者模式通过同步和阻塞队列实现了线程间的高效协作,有效地解决了多线程环境下的数据共享和通信问题。在实际开发中,可以根据需求选择适合的同步策略,如`synchronized`、`wait/notify`或`BlockingQueue`等。