`
gogole_09
  • 浏览: 201985 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

线程同步--生产者与消费者模式

阅读更多

  生产者与消费者模式简单介绍:

  生产者线程生产物品,然后将物品放置在一个空缓冲区中供消费者线程消费。消费者线程从缓冲区中获得物品,然后释放缓冲区。当生产者线程生产物品时,如果没有空缓冲区可用,那么生产者线程必须等待消费者线程释放出一个空缓冲区。当消费者线程消费物品时,如果没有满的缓冲区,那么消费者线程将被阻塞,直到新的物品被生产出来

 

以示例来说明问题:

以下程序参考至: http://www.iteye.com/topic/256991

 首先是产品类:

 

package consumerandproducter;


/**
 * 单纯的产品类
 * @author google
 *
 */
public class Product {
	private int productId=0;
	public Product(int id){
		this.productId=id;
	}
	public int getProductId() {
		return productId;
	}
	public String toString(){
		return "product "+productId;
	}
}

 

再是仓库(缓冲区):

  

package consumerandproducter;

/**
 * 模拟缓冲区,以栈为数据结构,先进后出
 * @author google
 *
 */
public class StoreHouse {
	private int base=0;
	private int top=0;
	private Product[] products=new Product[10];
	
	/**
	 * 入栈
	 * @param product
	 */
	public synchronized  void push (Product product) {
		while(top==products.length){
			//当前的线程已经放弃对资源的占有,唤醒已经被wait的线程,唤醒的线程由JVM决定,不按优先级确定
			notify();
			try {
				System.out.println("仓库已满,正在等待消费……");
				wait();//此线程处于等待状态
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		products[top]=product;
		top++;
	}
	
	/**
	 * 出栈
	 * @return
	 */
	public synchronized Product pop(){
		Product product=null;
		while(top==base){
			notify();
			try {
				System.out.println("仓库已空,正在等待生产……");
				wait();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		top--;
		product=products[top];
		products[top]=null;
		return product;
	}
}

 

 

接着是消费者:

  

package consumerandproducter;

public class Consumer implements Runnable {
	private String consumerName;
	//保留有缓冲区对象的引用,以便消费产品
	private StoreHouse storeHouse;
	
	public Consumer(String consumerName, StoreHouse storeHouse) {
		this.consumerName = consumerName;
		this.storeHouse = storeHouse;
	}

	public void run() {
		while(true){
			System.out.println("消费者"+consumerName+"已经消费"+storeHouse.pop());
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

	}
	
	public String getConsumerName() {
		return consumerName;
	}
	public void setConsumerName(String consumerName) {
		this.consumerName = consumerName;
	}

}

 

 

然后是生产者:

  

package consumerandproducter;

/**
 * 生产者类
 * @author google
 * 
 */
public class Producter implements Runnable {
	private String producterName;

	//	保留有缓冲区对象的引用,以便将生产的产品放入缓冲区
	private StoreHouse storeHouse;
	
	public Producter(String producterName, StoreHouse storeHouse) {
		this.producterName = producterName;
		this.storeHouse = storeHouse;
	}


	public String getProducterName() {
		return producterName;
	}


	public void setProducterName(String producterName) {
		this.producterName = producterName;
	}

	public void producterProduct(){
		//生产产品,并放入到仓库中
		int i=0;
		while(true){
			i++;
			Product product=new Product(i);
			storeHouse.push(product);
			System.out.println(producterName+"生产了");
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				return;
			}
		}
	}

	public void run() {
		producterProduct();
	}

}

 

 

 测试类:

  

package consumerandproducter;

import sun.security.krb5.internal.crypto.t;

public class Test {
	public static void main(String[] args) {
		StoreHouse storeHouse=new StoreHouse();
		Producter producter=new Producter("生产者",storeHouse);
		Consumer consumer=new Consumer("消费者",storeHouse);
		Thread t1=new Thread(producter);
		Thread t2=new Thread(consumer);
		t1.start();
		t2.start();
		/**
		 * ~输出(随机抽取输出,每次测试的结果可能都有稍许不同):
		 * 
				生产者生产了
				消费者消费者已经消费product 1
				生产者生产了
				消费者消费者已经消费product 2
				生产者生产了
				消费者消费者已经消费product 3
				生产者生产了
				消费者消费者已经消费product 4
				...........
				仓库已空,正在等待生产……
				生产者生产了
				生产者生产了
				生产者生产了
				生产者生产了
				.........
				仓库已满,正在等待消费……
			消费者消费者已经消费product 14
			消费者消费者已经消费product 13
			消费者消费者已经消费product 12
			消费者消费者已经消费product 11
			消费者消费者已经消费product 10
				......
				
		 */
	}
}

 

 小结:

    此问题主要是考察java间多线程通信与资源同步, 其中主要是对于notify与wait方法的使用上,还有对于线程间资源的共享,利用synchronized关键字,对共享资源的锁定,以达到线程同步的效果。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics