生产者-消费者问题是经典的多线程同步问题,可以使用Java中的wait()
和notify()
方法来解决。以下是一个简单的示例代码,展示了如何使用这些方法来处理生产者-消费者问题。
在这个示例中,我们有一个共享的缓冲区(队列),生产者生产数据并将其放入缓冲区,消费者从缓冲区中取出数据进行处理。我们使用wait()
和notify()
来确保生产者和消费者之间的正确同步。
import java.util.LinkedList; | |
import java.util.Queue; | |
class ProducerConsumer { | |
private final Queue<Integer> buffer = new LinkedList<>(); | |
private final int BUFFER_SIZE = 5; | |
private final Object lock = new Object(); | |
// 生产者线程 | |
class Producer implements Runnable { | |
@Override | |
public void run() { | |
int item = 0; | |
while (true) { | |
synchronized (lock) { | |
while (buffer.size() == BUFFER_SIZE) { | |
try { | |
System.out.println("Buffer is full. Producer is waiting."); | |
lock.wait(); | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
return; | |
} | |
} | |
buffer.add(item); | |
System.out.println("Produced: " + item); | |
item++; | |
lock.notify(); | |
try { | |
Thread.sleep(100); // 模拟生产时间 | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
return; | |
} | |
} | |
} | |
} | |
} | |
// 消费者线程 | |
class Consumer implements Runnable { | |
@Override | |
public void run() { | |
while (true) { | |
synchronized (lock) { | |
while (buffer.isEmpty()) { | |
try { | |
System.out.println("Buffer is empty. Consumer is waiting."); | |
lock.wait(); | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
return; | |
} | |
} | |
int item = buffer.poll(); | |
System.out.println("Consumed: " + item); | |
lock.notify(); | |
try { | |
Thread.sleep(150); // 模拟消费时间 | |
} catch (InterruptedException e) { | |
Thread.currentThread().interrupt(); | |
return; | |
} | |
} | |
} | |
} | |
} | |
public static void main(String[] args) { | |
ProducerConsumer pc = new ProducerConsumer(); | |
Thread producerThread = new Thread(pc.new Producer()); | |
Thread consumerThread = new Thread(pc.new Consumer()); | |
producerThread.start(); | |
consumerThread.start(); | |
} | |
} |
代码解释
- 共享缓冲区:使用一个
LinkedList
作为缓冲区,并设定一个固定的缓冲区大小BUFFER_SIZE
。 - 锁对象:使用一个
Object
类型的lock
对象来进行同步。 - 生产者线程:
- 在一个无限循环中,生产者会检查缓冲区是否已满。
- 如果缓冲区已满,生产者调用
lock.wait()
来等待,直到被消费者通知。 - 如果缓冲区未满,生产者将生产的项目添加到缓冲区中,并调用
lock.notify()
来通知可能等待的消费者。
- 消费者线程:
- 在一个无限循环中,消费者会检查缓冲区是否为空。
- 如果缓冲区为空,消费者调用
lock.wait()
来等待,直到被生产者通知。 - 如果缓冲区不为空,消费者从缓冲区中取出项目进行处理,并调用
lock.notify()
来通知可能等待的生产者。
- 主方法:创建并启动生产者和消费者线程。
这个示例展示了如何使用wait()
和notify()
来协调生产者和消费者线程之间的操作,从而避免竞争条件和死锁。