java模拟实现生产者---消费者问题

本文章为小编原创,请尊重文章的原创性,转载请注意写明转载来源:http://blog.csdn.net/u012116457


已知技术参数:
生产者消费者问题,描述一组生产者向一组消费者提供产品/消息。它们共享一个有界缓冲区,生产者向其中放产品/消息,消费者从中取产品/消息。只要缓冲区未满,生产者可放产品/消息,只要缓冲区有数据,消费者可取消息。即应满足下列二个同步条件:
1.只有在缓冲池中至少有一个缓冲区已存入消息后,消费者才能从中提取消息,否则消费者必须等待。
2.只有缓冲池中至少有一个缓冲区是空时,生产者才能把消息放入缓冲区,否则生产者必须等待。

设计要求:
要求设定一个缓冲池中有n个缓冲区,每个缓冲区存放一个消息,创建多个生产者,消费者,并在每个生产者消费者创建时、发出放/取产品申请时、正在放/取产品时和放/取产品结束时分别给出提示信息,并显示取/方产品前后的缓冲区状态,以检查所有处理都遵守相应的操作限制。


上代码:

最核心的代码:

package kcsj;
/**
 * 模拟实现生产者--消费者问题
 * 
 * @date 2014/06/24
 *
 */
public class ProductiveConsumption {
	private int front=0;             //队头
	private int next=0;              //队尾
	private int bufferLength;        //缓冲区大小
	private String buffer[];         //缓冲区
	private int emptyNum;          //空缓冲区数目
	public ProductiveConsumption(int bufferLength){
		this.bufferLength=bufferLength;
		buffer=new String[bufferLength];
		emptyNum=bufferLength;
	}
	//生产
	public synchronized void produce(String data){
		System.out.println("生产前,空缓冲区数目-----------"+emptyNum);
		System.out.println("***生产者正在生产"+data);
		while(full()){
			System.out.println("*****缓冲池已满,生产等待");
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();
		buffer[next]=data;
		next=(next+1)%bufferLength;
		System.out.println("****生产者成功生产:"+data);
		emptyNum--;
		System.out.println("生产后,空缓冲区数目-----------"+emptyNum);
	}
	//消费
	public synchronized void consum(){
		System.out.println("消费前,空缓冲区数目-----------"+emptyNum);
		while(empty()){
			System.out.println("*****缓冲池为空,消费等待");
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		System.out.println("***消费者正在消费"+buffer[front]);
		this.notify();
		System.out.println("****消费者成功消费:"+buffer[front]);
		front=(front+1)%bufferLength;
		emptyNum++;
		System.out.println("消费后,空缓冲区数目-----------"+emptyNum);
	}
	//缓冲池是否已满
	public boolean full(){
		if(emptyNum==0){
			return true;
		}
		return false;
	}
	//缓冲池是否为空
	public boolean empty(){
		if(bufferLength==emptyNum){
			return true;
		}
		return false;
	}

}



其他辅助代码:

package kcsj;
/**
 *创建生产者
 */ 
public class CreateProducer implements Runnable{
	ProductiveConsumption pc;
	int producerNum;
	public CreateProducer(ProductiveConsumption pc,int producerNum){
		this.pc=pc;
		this.producerNum=producerNum;
	} 
	public void run(){
		for(int i=0;i<producerNum;i++){
			Producer producer=new Producer(pc);
			try {
				Thread.sleep((int)(Math.random()*100));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}
}

package kcsj;
/**
 *创建消费者
 */ 
public class CreateConsumer implements Runnable{
	ProductiveConsumption pc;
	int consumerNum;
	public CreateConsumer(ProductiveConsumption pc,int consumerNum){
		this.pc=pc;
		this.consumerNum=consumerNum;
	} 
	public void run(){
		for(int i=0;i<consumerNum;i++){
			Consumer consumer=new Consumer(pc);
			try {
				Thread.sleep((int)(Math.random()*100));
			} catch (InterruptedException e) {
				e.printStackTrace();
			} 
		}
	}
}

package kcsj;

public class Producer{
	ProductiveConsumption pc;
	public Producer(ProductiveConsumption pc){
		this.pc=pc;
		System.out.println("*成功创建一个生产者");
		apply();
	} 
	public void apply(){
		char c=(char)(Math.random()*26+'A');  
		String data=String.valueOf(c);
		System.out.println("**生产者发出请求");
		pc.produce(data);
	}

}

package kcsj;

public class Consumer{
	ProductiveConsumption pc;
	public Consumer(ProductiveConsumption pc){
		this.pc=pc;
		System.out.println("*成功创建一个消费者");
		apply();
	} 
	public void apply() {
		System.out.println("**消费者发出请求");
		pc.consum();
	}
}

package kcsj;

import java.util.Scanner;

public class Test {

	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		System.out.println("输入缓冲区大小");
		int buffLength=sc.nextInt();
		System.out.println("输入生产者和消费者个数");
		int prodecerNum=sc.nextInt();
		int consumerNum=sc.nextInt();

		ProductiveConsumption pc=new ProductiveConsumption(buffLength); 
		Runnable cp=new CreateProducer(pc,prodecerNum); 
		Runnable cc=new CreateConsumer(pc,consumerNum); 
		Thread t1=new Thread(cp); 
		Thread t2=new Thread(cc);
		t1.start(); 
		t2.start(); 
	}
}


一、 课程设计目的 在多道程序环境下,进程同步问题十分重要,通过解决“生产者-消费者问题,可以帮助我们更好的理解进程同步的概念及实现方法。掌握线程创建和终止的方法,加深对线程和进程概念的理解,会用同步与互斥方法实现线程之间的进行操作。 在学习操作系统课程的基础上,通过实践加深对进程同步的认识,同时,可以提高运用操作系统知识解决实际问题的能力;锻炼实际的编程能力、创新能力及团队组织、协作开发软件的能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。 二、 课程设计内容 模拟仿真“生产者-消费者问题的解决过程及方法。 三、 系统分析与设计 1、 系统分析 在OS中引入进程后,虽然提高了资源的利用率和系统的吞吐量,但由于进程的异步性,也会给系统造成混乱,尤其是在他们争用临界资源时。为了对多个相关进程在执行次序上进行协调,以使并发执行的诸程序之间能有效地共享资源和相互合作,使程序的执行具有可再现性,所以引入了进程同步的概念。信号量机制是一种卓有成效的进程同步工具。 在生产者---消费者问题中应注意(信号量名称以多个生产者和多个消费者中的为例):首先,在每个程序中用于互斥的wait(mutex)和signal(mutex)必须成对出现;其次,对资源信号量empty和full的wait和signal操作,同样需要成对地出现,但它们分别处于不同的程序中。生产者消费者进程共享一个大小固定的缓冲区。其中,一个或多个生产者生产数据,并将生产的数据存入缓冲区,并有一个或多个消费者从缓冲区中取数据。 2、 系统设计: 系统的设计必须要体现进程之间的同步关系,所以本系统采用2个生产者、2个消费者 和20个缓冲区的框架体系设计。为了更能体现该系统进程之间的同步关系,系统的生产者消费者的速度应该可控,以更好更明显的表现出结果。 为了使本系统以更加简单、直观的形式把“消费者-生产者问题表现出来,我选择了使 用可视化界面编程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

光光-Leo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值