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

本文通过Java代码模拟了生产者消费者问题,实现了多个生产者与消费者间的同步操作。使用有界缓冲区确保线程安全,展示了如何在多线程环境下进行资源的生产和消费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文章为小编原创,请尊重文章的原创性,转载请注意写明转载来源:http://blog.youkuaiyun.com/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(); 
	}
}


一、设计要求 设计一个模拟仿真“生产者-消费者问题的解决过程及方法的程序。 主要内容是P、V操作过程的设计与实现。生产消费者问题是操作系统设计中经常遇到的问题。多个生产者消费者线程访问在共享内存中的环形缓冲。生产者生产产品并将它放入环形缓冲,同消费者从缓冲中取出产品并消费。当缓冲区生产者阻塞并且当缓冲区有空生产者又重新工作。类似的,消费者当缓冲区空阻塞并且当缓冲区有产品又重新工作。显然,生产者消费者需要一种同步机制以协调它们的工作。 二、系统功能 本程序模拟实现了“生产者-消费者问题的解决过程,用图形界面动态演示了P、V操作过程以及生产者消费者进程之间的工作流程。 本程序使用的算法是典型的P、V操作使用信号量解决“生产者-消费者问题。 本程序在界面上使用了Java的swing接口函数,用矩形条表示生产者进程中待生产的产品,并设置了三个分区分别表示生产者进程待生产的产品、公共缓冲池中已生产的产品消费者进程已消费的产品,以动画的效果动态演示了待生产产品变成消费者进程中已消费产品的过程,以及在这一过程中生产者进程消费者进程协调工作的过程。在程序运行过程中使用了两个生产者线程两个消费者线程并发工作,并使用了线程随机休眠的策略,即每个线程在完成一次生产过程或消费过程后随机休眠1至10秒钟。这一策略能保证生产者消费者之间的运行顺序被打破,从而产生生产产品消费产品之间的矛盾(即没有产品可消费的情况下消费者试图向公共缓冲池取产品消费、公共缓冲池里的产品已的情况下生产者试图生产产品放入缓冲池)。因为生产者生产产品消费者消费产品都是随机的,所以产生的矛盾也是不可预知的,在这种情况下,才能检验所使用的算法是否健壮高效。而本程序正是基于这种思想设计出来的,用来模拟生产者消费者问题的解决过程。 本程序在运行提供友好的交互界面,且操作简单,在模拟过程中各种情况有相应文字提示,并伴有相应的图像变化,如:当没有产品可消费的情况下消费者试图向公共缓冲池取产品消费,消费者进程阻塞,公共缓冲池随之变成红色,文字提示框内显示warning: it's empty!Consumer is block;当缓冲池生产者试图生产产品并向缓冲池放入产品生产者进程阻塞,公共缓冲池里的每一个产品变成黄色,问题提示框显示warning: it's full!Producer is block。整个模拟过程通俗易懂,利于理解,能很好的帮助使用者加强生产者消费者问题的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值