话不多说直接上代码,注解中有解释!!
1.测试类
/**
* 生产者和消费者问题(重点)
* 生产者不断的往仓库中存放产品,消费者从仓库中消费产品
* 其中生产者和消费者都可以有若干个
* 仓库规则:容量有限,库满时不能存放,库空时不能取产品
* @author
*
*/
public class ProtuctTest {
public static void main(String[] args) throws InterruptedException {
//主函数,建一个仓库里面有10个空位
Storage storage = new Storage();
//两个消费者
Thread consumer1 =new Thread(new Consumer(storage));
consumer1.setName("消费者1");
Thread consumer2 =new Thread(new Consumer(storage));
consumer2.setName("消费者2");
//两个生产者,每个生产者生产10个
Thread product1 = new Thread(new Producer(storage));
product1.setName("生产者1");
Thread product2 = new Thread(new Producer(storage));
product2.setName("生产者2");
product1.start();
product2.start();
Thread.sleep(1000);
consumer1.start();
consumer2.start();
}
}
2.生产者实体类 product.java
public class Product {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造函数
public Product(int id, String name) {
super();
this.id = id;
this.name = name;
}
//toString 方法
@Override
public String toString() {
return "Product [产品ID=" + id + "产品名称=" + name + "]";
}
}
3.生产者 Producter.java
import java.util.Random;
public class Producer implements Runnable{
//生产者要向仓库里面放东西
private Storage storage;
public Producer(Storage storage) {
super();
this.storage = storage;
}
@Override
public void run() {
int i = 0;
Random r= new Random();
while(i<10){
i++;
Product product =new Product(i,"名字"+r.nextInt(100));
storage.put(product);
}
}
}
4.消费者Consumer.java
public class Consumer implements Runnable{
private Storage storage;
//构造函数,消费者使用这个仓库
public Consumer(Storage storage) {
super();
this.storage = storage;
}
@Override
public void run() {
int i=0;
while(i<10){ //每个消费者都拿10个产品
i--;
storage.pop();//从仓库中拿出一个产品
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}//然后睡一会
}
}
}
5.仓库类Storage.java
public class Storage {
//建立一个仓库产品容量
private Product[] products=new Product[10];
//开始时放入产品的个数为0
int top = 0;
//生产者从仓库中放入商品(互斥的synchronized修饰,一次只能有一个线程运行此代码块)
public synchronized void put(Product product) {
//开始循环
while(top == products.length){ //当产品个数小于产品的最大容量时
System.out.println("product waiting");
try {
wait();//仓库已满,需要等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
products[top++]=product; //把产品放入仓库
System.out.println(Thread.currentThread().getName()+"生产了一个产品"+product);
System.out.println("pruduct notifyAll");
notify();//唤醒其他线程
}
//消费者从仓库中拿出产品
public synchronized Product pop() {
while(top == 0){
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
--top;
//获取到取出的这个产品Id和name;放到一个p对象中
Product p =new Product(products[top].getId(), products[top].getName());
products[top]=null; //把当前拿走的top位置清空
System.out.println(Thread.currentThread().getName()+"消费了产品"+p);
System.out.println("pruduct notifyAll");
notify();//唤醒其他线程
return p;
}
}