生产者消费者问题(就是存放拿取问题)
(1)什么是消费者生产者问题?很多情况下,我们需要这样的模型。大家可以想象一下吃自助餐。在自助餐的公共区域有很多食物,我们(消费者)可以去挑选食物。然而,这时候食物被我们选没了,于是大家伙都等待。在等待什么呢?等待厨师做出新的一批食物放置上来,我们就可以继续选择我们喜爱的食物。
同样,如果反过来理解的话也可以。我们可以制造一些请求,这些请求放到一个队列中。队列的另一端会处理请求。如果队列中有请求,那么处理请求,没有的话等待请求的到来。我们在队列中放入请求的时候,如果队列满了,我们就等待处理请求处理完一个请求,于是我们可以放入新的请求。
我们用代码来模拟第二种情况:
Request: 请求对象
RequestContainer: 存放请求的容器
ProcessRequestThread: 处理请求的线程
MakeRequestThread: 制造请求的线程
(2)核心的就是必须具备4个类,外加1个运行类,所以总共5个类。
(1) 代码解析图。
在程序演示中还涉及到几点:1.有一个测试容器容量的方法
2.生产者和消费者线程要休眠
3.在为了保证一个容器时,涉及到了单例模式。分三步,第一
在生产者和消费者类的构造方法里设置不许传进容器参数,
第二是在最后的运行类里边实现容器类初始化;第三是在容器类里边实现单例模式。
java代码演示
第一个类:Product类
package com.langsin.TestProductCustorm;
public class Product {
private int id;
private String name;
public String toString() {
return "Product [id=" + id + ", name=" + 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;
}
}
第二个类:ProductContainer类
package com.langsin.TestProductCustorm;
import java.util.LinkedList;
public class ProductContainer {
/*
* 前三行的就是传说中的单例模式
*/
private static ProductContainer instance =null;
private ProductContainer(){}
public static synchronized ProductContainer getinstance(){
if(instance==null){
instance=new ProductContainer();
}
return instance;
}
//建立一个容器,这个容器的存储方式是队列的形式
private static LinkedList<Product> list =new LinkedList<Product>();
//设置容器大小
private static int MaxSize =10;
/*
* 生产者存入商品
*/
public synchronized void putProduct(Product product){
while(list.size()>=MaxSize){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
list.addLast(product);
// System.out.println(product);
notifyAll();
}
/*
* 消费者拿取商品
*/
public synchronized Product getProduct(){
while(list.size()<=0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Product product = list.removeFirst();
// System.out.println(product);
notifyAll();
return product;
}
//检查容器的大小变化
public synchronized int cheaksize(){
return list.size();
}
}
第三个类:ProductThread类
package com.langsin.TestProductCustorm;
public class ProductThread implements Runnable{
ProductContainer pc =null;
//设置构造方法
public ProductThread(ProductContainer pc){
this.pc =pc;
}
@Override
public void run() {
// TODO Auto-generated method stub
int i = 0;
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Product p =new Product();
p.setId(++i);
p.setName("产品的id"+i);
pc.putProduct(p);
}
}
}
第四个类:CustormerThread类
package com.langsin.TestProductCustorm;
public class CustormerThread implements Runnable {
ProductContainer pc =null;
//设置构造方法
public CustormerThread(ProductContainer pc ) {
// TODO Auto-generated constructor stub
this.pc =pc;
}
@Override
public void run() {
// TODO Auto-generated method stub
Product p =pc.getProduct();
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("消费者消费的产品是:"+p.toString());
}
}
}
第五个类:Go类
package com.langsin.TestProductCustorm;
public class Go {
public static void main(String[] args) {
//调用容器类的单例模式
final ProductContainer pc =ProductContainer.getinstance();
for(int i =0;i<1;i++){
//将单例模式的对象传给生产者线程
new Thread(new ProductThread(pc)).start();
}
for(int i =0;i<10;i++){
//将单例模式的对象传给消费者线程
new Thread(new CustormerThread(pc)).start();
}
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(300);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int size =pc.cheaksize();
System.err.println(size);
}
}
}).start();
}
}