Java实践之路——多线程之生产者消费者模型

一、环境

1、平台:MyEclipse8.5/JDK1.5

二、概述

1、目标:用java实现生产者消费者模型

2、生产者消费者模型描述

1)、生产者仅仅在仓储未满时候生产,仓满则停止生产。

2)、消费者仅仅在仓储有产品时候才能消费,仓空则等待。

3)、当消费者发现仓储没产品可消费时候会通知生产者生产。

4)、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

三、开发调试

1、编写仓库代码,具体代码如下

package org.cyxl.thread;

/**
 * 仓库
 * @author cyxl
 *
 */
public class Godown {
	private int max_size=100;	//最大库存量
	private int curr_size=0;	//当前库存量
	
	public Godown()
	{}
	
	public Godown(int max_size)
	{
		this.max_size=max_size;
	}
	
	
	public int getMax_size() {
		return max_size;
	}

	public void setMax_size(int maxSize) {
		max_size = maxSize;
	}

	public int getCurr_size() {
		
		return curr_size;
	}
	public  void setCurr_size(int currSize) {
		curr_size = currSize;
	}
	
	/**
	 * 生产时增加库存量,注意同步
	 * @param size	生产数量
	 */
	public synchronized void add(int size)
	{
		while((this.curr_size+size)>this.max_size)
		{
			System.out.println("生产"+size+"后"+(this.curr_size+size)+"超过了仓库的最大库存量"+this.max_size+",所以不生产");
			try {
				//仓满停止生产,直到可以生产为止
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.curr_size+=size;
		System.out.println("生产"+size+",当前库存量为"+curr_size);
		//唤醒所有该对象的其他线程,通知消费者消费
		this.notifyAll();
	}
	
	/**
	 * 消费者减少库存量,注意同步
	 * @param size	消费数量
	 */
	public synchronized void minus(int size)
	{
		while(this.curr_size<size)
		{
			System.out.println("库存量"+getCurr_size()+"不足"+size+",请联系生产");
			try {
				//数量不够一直等待,直到存库达到该数量
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.curr_size-=size;
		System.out.println("消费了"+size+",当前库存量为"+curr_size);
		//唤醒所有该对象的其他线程,通知生产者生产
		this.notifyAll();
	}

}

2、编写消费者代码

package org.cyxl.thread;

/**
 * 消费者
 * @author cyxl
 *
 */
public class Consumer implements Runnable{
	private Godown godown;	//仓库
	private int num;		//消费数量
	
	public Consumer()
	{}
	
	public Consumer(Godown godown,int num)
	{
		this.godown=godown;
		this.num=num;
	}

	public Godown getGodown() {
		return godown;
	}

	public void setGodown(Godown godown) {
		this.godown = godown;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public void run() {
		//消费数量num
		godown.minus(num);
	}
	
	

}

3、编写生产者代码

package org.cyxl.thread;

/**
 * 生产者
 * @author cyxl
 *
 */
public class Producer implements Runnable{
	private Godown godown;	//仓库
	private int num;		//生产数量
	public Godown getGodown() {
		return godown;
	}
	public void setGodown(Godown godown) {
		this.godown = godown;
	}
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public Producer()
	{}
	
	public Producer(Godown godown,int num)
	{
		this.godown=godown;
		this.num=num;
	}
	public void run() {
		//生产数量num
		godown.add(num);
	}
	
}

4、编写销售者,销售者作为联系生产者、消费者和仓库的桥梁

package org.cyxl.thread;

/**
 * 销售员
 * @author Administrator
 *
 */
public class Solder {
	public static void main(String[] args)
	{
		//建一个容量为200的仓库
		Godown godown=new Godown(200);
		//消费者消费20
		Consumer c1=new Consumer(godown,20);
		Thread ct1=new Thread(c1);
		ct1.start();
		//消费者消费50
		Consumer c2=new Consumer(godown,50);
		Thread ct2=new Thread(c2);
		ct2.start();
		//生产者生产30
		Producer p1=new Producer(godown,30);
		Thread pt1=new Thread(p1);
		pt1.start();
		//生产者生产80
		Producer p2=new Producer(godown,80);
		Thread pt2=new Thread(p2);
		pt2.start();
		//消费者消费30
		Consumer c3=new Consumer(godown,30);
		Thread ct3=new Thread(c3);
		ct3.start();
		
	}
}

5、测试结果

库存量0不足20,请联系生产
库存量0不足50,请联系生产
生产30,当前库存量为30
库存量30不足50,请联系生产
消费了20,当前库存量为10
库存量10不足50,请联系生产
生产80,当前库存量为90
消费了50,当前库存量为40
消费了30,当前库存量为10

四、总结

1、多线程特别应注意方法的同步

2、该程序涉及的知识点有多线程,线程同步,wait方法,notify方法或者notifyAll方法

3、以上测试的结果是随机的,但最后的结果是一定的,也就是最后的库存量为10

你可能感兴趣的:(java,thread,多线程,MyEclipse,Class,产品)