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();
	}
}

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

时间: 2024-10-01 04:28:23

java模拟实现生产者---消费者问题的相关文章

Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. BlockingQueue 下面来逐一分析. 1. wait()/notify() 第一种实现,利用根类Object的两个方法wait()/notify(),来停止或者唤醒线程的执行:这也是最原始的实现. 1 public class WaitNotifyBroker<T> implements Broker&

JAVA多线程之生产者消费者

生产者消费者并发编程: 假设仓库有10个仓位,分别有10个生产者和10个消费者,生产者不断生产产品,放入仓库的仓位中,而消费者则不断从仓库中获取产品, 如果仓库已满,则生产者要等待,等消费者消费后,空出仓位后,再继续放入产品. 反之如果仓库已空,则消费者要等待,等待生产者生产出产品后,再继续消费产品. 关于生产者.消费者有四种实现方式 1,wait,nofity方式 2,ReentrantLock锁的await()和signal() 3,阻塞队列的方式 4,Semaphore 信号量方式 下面分

java wait notifyAll 生产者 消费者 BlockingDeque

--用wait notifyAll来实现生产者与消费者模式,如下 package com.collonn.procon2; import java.util.LinkedList; import java.util.concurrent.atomic.AtomicInteger; public class PCTest { // the max number of product in product pool public static final int QUEUE_MAX_SIZE = 3

java多线程解决生产者消费者问题

import java.util.ArrayList; import java.util.List; /** * Created by ccc on 16-4-27. */ public class Test { public static void main(String[] args) { GunClip clip = new GunClip(); Producer p = new Producer(clip); customer c = new customer(clip); p.star

Java多线程:生产者消费者更佳的解决方法(确定不会出现死锁)

今天看了一片博文,讲Java多线程之线程的协作,其中作者用程序实例说明了生产者和消费者问题,但我及其他读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的例子也都存在bug,经过仔细研究发现其中的问题,并解决了,感觉有意义贴出来分享下. 下面首先贴出的是有bug的代码,一个4个类,Plate.java: package CreatorAndConsumer; import java.util.ArrayList; import java.util.List; /** * 盘子,表示共享的资源

java设计模式之生产者/消费者模式

什么是生产者/消费者模式? 某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类.函数.线程.进程等).产生数据的模块,就形象地称为生产者:而处理数据的模块,就称为消费者.在生产者与消费者之间在加个缓冲区,我们形象的称之为仓库,生产者负责往仓库了进商品,而消费者负责从仓库里拿商品,这就构成了生产者消费者模式.结构图如下: 生产者消费者模式有如下几个优点: 1.解耦   由于有缓冲区的存在,生产者和消费者之间不直接依赖,耦合度降低. 2.支持并发   由于生产者与消费

Java多线程实现生产者消费者延伸问题

在操作系统中有一类问题被称为生产者消费者问题:意为,有数个生产者生产产品,有数个消费者消费产品,他们共享一定数量的缓存. 这里用java多线程编程,实现生产者消费者问题的一种延伸,橘子苹果问题. 题目如下: 有苹果橘子生产者各20个,有苹果橘子消费者各20个,他们公用20个缓存区.要求能随时查看缓存区内容,随时查看生产消费内容情况,随时暂停生产开始生产. 我们的实现思路: 1.首先创建一个缓存区类,其中包含静态的,长度大小为20的数组,用来存放和取出生产的产品:一个静态的日志变量List,用来记

Java多线程之生产者消费者问题&amp;lt;一&amp;gt;:使用synchronized keyword解决生产者消费者问题

今天看了一片博文,讲Java多线程之线程的协作,当中作者用程序实例说明了生产者和消费者问题,但我及其它读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的样例也都存在bug,经过细致研究发现当中的问题.并攻克了,感觉有意义贴出来分享下. 以下首先贴出的是有bug的代码,一个4个类.Plate.java: package CreatorAndConsumer; import java.util.ArrayList; import java.util.List; /** * 盘子,表示共享的资源

Java 线程池 +生产者消费者+MySQL读取300 万条数据

1.1需求 数据库300 万条用户数据 ,遍历获取所有用户, 各种组合关联, 获取到一个新的json ,存到redis 上. 1.2 难点 数据库比较多, 不可能单线程查询所有的数据到内存. 1.3解决办法 多线程读取, 生产者 每次获取200 条数据, 消费者去消费.(这里 主要是根据MySQL分页去获取下一个200 条数据) 1.4 代码 1.4.1 调用方法 /** * 线程启动 */ public void update() { //redis操作类 HashRedisUtil redi