生产者消费问题介绍
定义
一群生产者向一群消费者提供产品,生产者与消费者共享缓存区,其中生产者生产产品,消费者消费产品。
规则
- 当缓冲区满时,不允许生产者向缓冲区中存产品。
- 当缓冲区空时,不允许消费者从缓存区中取产品。
- 每个时刻仅允许1个生产者或消费者存取数据。
操作系统的信号量解决生产者-消费者问题
int empty = n; //信号量:缓冲区中的空位的个数
int full = 0; //信号量:缓冲区中的数据的个数
int mutex = 1;
/*
生产者生产过程
*/
p(empty);
p(mutex);
prodece();
v(mutex);
v(full);
/*
消费者消费过程
*/
p(full);
p(mutex);
consume();
v(mutex);
v(empty);
使用Java中的Object.wait(),Object.notify()实现
class Product
{
String name;
public Product(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "Product [name=" + name + "]";
}
}
class Storage
{
int size;
int top;
Product[] products;
public Storage(int size) {
super();
this.size = size;
this.products = new Product[size];
this.top = 0;
}
// 放产品
public synchronized void push(Product product, int id)
{
while (top == size)
{
try {
/*
* 如果仓库已满,调用wait释放锁,当前线程进入该对象的等待队列,
* 等待被其他线程唤醒,被唤醒并且获得锁后,线程恢复运行
*/
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//装商品
products[top] = product;
System.out.println("生产者" + String.valueOf(id) + "生产了: " + product.name);
top++;
//唤醒其他等该该对象锁的线程
notifyAll();
}
// 拿产品
public synchronized Product pop(int id)
{
Product product;
while (top == 0)
{
try {
/*
* 仓库为0,调用wait释放锁,当前线程进入当前对象锁的等待队列,
* 等待被其他线程唤醒,被唤醒并且获得锁后,线程恢复运行
*/
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
top--;
product = products[top];
System.out.println("消费者" + String.valueOf(id) + "消费了: " + product.name);
//唤醒其他线程
notifyAll();
return product;
}
}
// 生产者
class Producer extends Thread
{
private Storage storage;
private int id;
Product product;
public Producer(Storage storage, int id, Product product) {
super();
this.storage = storage;
this.id = id;
this.product = product;
}
//生产一件产品
@Override
public void run() {
while (true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
storage.push(product, id);
}
}
}
//消费者
class Consumer extends Thread
{
private Storage storage;
private int id;
public Consumer(Storage storage, int id) {
super();
this.storage = storage;
this.id = id;
}
//消费产品
@Override
public void run() {
while(true)
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
storage.pop(id);
}
}
}
public class Test {
public static void main(String[] args) {
// 设仓库大小为4
Storage storage = new Storage(4);
// 设生产产品数为8
String[] s = new String[8];
s[0] = "黄瓜";
s[1] = "萝卜";
s[2] = "白菜";
s[3] = "牛肉";
s[4] = "猪肉";
s[5] = "鸡肉";
s[6] = "茄子";
s[7] = "番茄";
for (int i = 0; i < 8; i++)
{
Producer producer = new Producer(storage, i, new Product(s[i]));
Consumer consumer = new Consumer(storage, i);
producer.start();
consumer.start();
}
}
}