生产者-消费者模型
最新接触多线程内容,解决了困惑我许久的 线程锁 以及 线程通信 问题,在此以经典的 生产者-消费者 为典例在此记录。
问题描述
生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
问题分析
- 线程数?生产者线程,消费者线程
- 共享数据?店员(或产品数量)
- 如何解决线程的安全问题?同步机制,有三种方法
- 是否涉及线程的通信?是
代码实现
共享数据-店员(产品数量)
/**
* 店员:共享资源-产品件数
*/
class Clerk {
private int num = 0;
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
}
线程-生产者
/**
* 生产者
*/
class Producer implements Runnable {
private final Clerk clerk;
public Producer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
produceProduct();
}
}
/**
* 生产商品
*/
private void produceProduct() {
synchronized (clerk) {
if (clerk.getNum() < 20) {
clerk.setNum(clerk.getNum() + 1);
System.out.println(Thread.currentThread().getName() + "开始生产了" + clerk.getNum() + "件商品");
clerk.notifyAll();
} else {//超过数量,停止生产
try {
clerk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
线程-消费者
/**
* 消费者
*/
class Consumer implements Runnable {
private Clerk clerk;
public Consumer(Clerk clerk) {
this.clerk = clerk;
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
consumeProduct();
}
}
/**
* 消费商品
*/
private void consumeProduct() {
synchronized (clerk) {
if (clerk.getNum() > 0) {
System.out.println(Thread.currentThread().getName() + "消费了第" + clerk.getNum() + "件商品");
clerk.setNum(clerk.getNum() - 1);
clerk.notify();
} else {//商品不足,停止消费
try {
clerk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
代码测试
/**
* 线程通信:生产者-消费者
* 生产者(Productor)将产品交给店员(Clerk),而消费者(Customer)从店员处取走产品,
* 店员一次只能持有固定数量的产品(比如:20),如果生产者试图生产更多的产品,店员
* 会叫生产者停一下,如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品
* 了,店员会告诉消费者等一下,如果店中有产品了再通知消费者来取走产品。
*
* @author yanjq
*/
public class ProducerConsumerTest {
public static void main(String[] args) {
//店员对象,并充当锁
Clerk clerk = new Clerk();
Producer producer = new Producer(clerk);
Consumer consumer1 = new Consumer(clerk);
Consumer consumer2 = new Consumer(clerk);
Thread producerThread = new Thread(producer);
Thread consumerThread1 = new Thread(consumer1);
Thread consumerThread2 = new Thread(consumer2);
producerThread.setName("生产者①");
consumerThread1.setName("消费者①");
consumerThread2.setName("消费者②");
producerThread.start();
consumerThread1.start();
consumerThread2.start();
}
}
本文介绍了Java中使用多线程解决生产者-消费者问题的实现方式。通过一个经典的例子,展示了如何利用线程同步机制(如wait()和notifyAll())确保线程安全,并实现线程间的通信。生产者在产品达到最大库存时会被阻塞,消费者在商品不足时也会等待,从而达到协调生产与消费的目的。
1702

被折叠的 条评论
为什么被折叠?



