`
gogole_09
  • 浏览: 205563 次
  • 性别: 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关键字,对共享资源的锁定,以达到线程同步的效果。

分享到:
评论

相关推荐

    多进程同步-生产者消费者模式-C实现

    在这个场景下,我们关注的是一个经典的并发编程模型——生产者消费者模式。该模式是多进程同步的一种典型应用,通过它我们可以高效地管理数据的生产和消费。 生产者消费者模式基于操作系统提供的信号量(Semaphore...

    linux下的多线程实例--生产者消费者

    1. **生产者消费者模型**:一种用于解决多线程环境中资源分配和同步问题的经典设计模式。其中,“生产者”负责生成数据,“消费者”负责处理这些数据。 2. **多线程编程**:在单个程序中创建多个并发执行路径的技术...

    Java多线程 生产者-消费者模式

    总之,Java中的生产者-消费者模式是多线程编程中解决数据共享和同步问题的有效手段,通过合理利用`BlockingQueue`等并发工具类,我们可以构建高效、稳定的多线程应用。在开发过程中,了解和掌握这种模式有助于提高...

    生产者和消费者模式多线程

    创建一个简单的生产者消费者模型,可以使用以下伪代码: ```java class Producer implements Runnable { private final BlockingQueue<String> queue; public Producer(BlockingQueue<String> queue) { this....

    多线程简易实现生产者消费者模式

    生产者消费者模式是一种经典的多线程同步问题解决方案,它源于现实世界中的生产流水线,用于描述生产者(Producer)和消费者(Consumer)之间的协作关系。在这个模式中,生产者负责生成产品并放入仓库,而消费者则从...

    java多线程实现生产者和消费者

    通过理解和掌握这些知识点,开发者能够有效地实现生产者-消费者模式,解决并发编程中的数据共享和协作问题。在实际项目中,这个模式常用于优化系统性能,尤其是在I/O密集型或计算密集型的应用中。

    java多线程例子-生产者消费者

    通过这个示例,我们不仅了解了生产者消费者模式,还学习了Java并发编程中`BlockingQueue`接口的使用,以及如何创建和管理线程。这是一个基础但非常实用的例子,有助于理解多线程环境中的同步和协作。在实际应用中,...

    生产者-消费者多线程处理

    在Java中,可以使用`BlockingQueue`接口来实现生产者-消费者模式,它已经内置了线程安全的队列操作。生产者可以使用`offer()`方法添加元素,消费者则用`take()`方法取出元素,这两个方法会自动处理等待和唤醒操作。 ...

    用多线程同步方法解决生产者-消费者问题(操作系统课设)

    针对生产者-消费者问题,多线程同步方法提供了一种有效且可靠的解决方案。在本课程设计中,采用的是Linux环境下的C语言编程,利用了信号量(Semaphore)和互斥锁(Mutex)来实现线程间的同步和互斥访问。 - **信号...

    多线程_生产者与消费者模式示例

    线程池可以配合生产者消费者模式,例如通过提交任务到线程池来实现生产者,线程池中的工作线程充当消费者角色。 在使用生产者消费者模式时,需要注意以下几点: - **线程安全**:确保所有的操作都是线程安全的,...

    c#多线程之生产者消费者

    综上所述,C#中的生产者消费者模式涉及线程同步、数据结构、异常处理等多个知识点,理解和熟练运用这些概念对于编写高效、可靠的并发程序至关重要。通过实践和优化,我们可以创建出能充分利用多核处理器能力、运行...

    生产消费者队列(c#),用于线程的队列自动同步

    在多线程编程中,生产者消费者模型是一种常见的设计模式,用于解决线程间的通信和同步问题。在C#中,我们可以利用各种机制实现这样的队列。本篇将详细讲解如何在C#中构建一个生产消费者队列,以及它如何帮助优化线程...

    Linux 多线程实现生产者消费者模式.pdf

    总结来说,Linux多线程实现生产者消费者模式涵盖了多线程创建、线程同步与互斥、锁机制、条件变量以及线程屏障等核心知识点。这些知识点是Linux下进行高级多线程编程不可或缺的部分,对于理解现代操作系统中多任务...

    生产者 消费者 模式 c++

    生产者消费者模式是一种多线程或并发编程中的经典设计模式,它主要用于解决系统资源的高效利用和同步问题。在C++中实现生产者消费者模式,我们可以利用C++11及更高版本提供的线程库()、互斥量()、条件变量()等...

    架构设计 -- 生产者/消费者模式

    【生产者/消费者模式】是一种常见的并发编程和系统设计模式,它主要解决的是在多线程环境下,如何协调生产者和消费者之间的数据处理问题。在软件开发中,生产者通常是生成数据的一方,而消费者则是处理这些数据的...

    典型的多线程--生产和消费

    "典型的多线程--生产和消费"这个主题,通常指的是生产者-消费者问题,这是一种经典的设计模式,用于解决如何在一个数据结构(如队列)中高效地存储和检索数据,同时避免生产者过于快速地生成数据而消费者无法及时...

    利用单线程完成的生产者与消费者程序

    然而,给定的标题“利用单线程完成的生产者与消费者程序”表明,这个程序是在单线程环境中实现的,这意味着没有并发线程,而是通过某种机制模拟了生产者和消费者的行为。 生产者-消费者模型通常用于处理数据流,...

    多线程间通信:多生产者-多消费者实例

    总之,多生产者-多消费者模式是并发编程中的重要设计模式,通过合理利用同步机制,能够有效地解决线程间的通信问题,提高系统的并发性能。在Java中,我们可以借助`BlockingQueue`等工具实现这一模式,从而构建高效、...

    java多线程(生产者与消费者)

    6. **死锁与活锁**:在实现生产者消费者模式时,需要警惕死锁和活锁的情况。死锁是指两个或多个线程相互等待对方释放资源,导致无法继续执行。活锁则是线程不断地尝试获取资源但总是失败,从而陷入无限循环。正确的...

Global site tag (gtag.js) - Google Analytics