`
greemranqq
  • 浏览: 975686 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论
阅读更多

题外话:从中秋请假到现在,接近20天的假期,让我彻底耍晕了,现在来写代码,发现始终没进入状态。以后建议大家没特殊事情,还是别请这么久啦,分开耍,有利于放松,也不至于耍得忘乎所以。我是一直想做互联网 并发 大数据方面的工作,有兴趣才有动力嘛,企业开发感觉活力不强,太多重复的劳动,还是喜欢研究 解决问题,有挑战的东东。线程这块,生产者与消费者模型一直是很经典的东东,这里我用自己的理解分享一下,有误的地方,还请大家指正哦~。~ 和我有相同发展方向的,可以加个QQ:315040617  一起学习研究哦!

 

 

1、解释

       从字面上来说,有一个生产者,负责生产产品,当然还有一个消费者,用来消费产品。这个好像很简单啦,假设有一个食品生产厂,然后我来买这些食品(有点废话了)。当然实际情况来看,我不可能专门跑到食品厂区买食品,多麻烦啦,一般情况是食品生产好了,会运送到一个卖食品的地方存放这,比如超市。我们称这样一个地区叫做仓库,那么一个简单的消费模型就诞生了!



 

2、变化

      虽然整个图形很简单,但是变化的情况是很多的,我们大概罗列一下:

      a.生产者 产品还没生产出来,仓库是空了,消费者就无法消费,如何处理?

      b.生产者 产品生产过多,消费者来不及消费,仓库放不下,如何处理?

      c.存在多个消费者,看上了仓库中同一个产品,如何处理?



 

3.程序设计

    下面我们模拟整个操作,来用代码实现,看看效果呢。

    3.1 我们先将主体设计出来,肯定有 生产者 ,仓库,消费者 3个对象。

   

package com;

import java.util.Random;

/**
 * 
 * 这是消费者
 *
 */
public class Customer {
	
	// 买到的商品数量
	private Integer count;
	// 用户的名字
	private String name;
	
	public Integer getCount() {
		return count;
	}
	public void setCount(Integer count) {
		this.count = count;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getName() {
		return name;
	}
	public Customer(){
		// 这里我们用随机 数字,来表示 用户的名字
		Random random = new Random();
		int num = random.nextInt(100);
		setName("customer_"+num);
	}
	
}

 

package com;
/**
 * 
 * 这是生产者
 *
 */
public class Producer {
     // 作为生产者,肯定知道生产的数据量
	 private Integer count;// 产量
	 
	 public Integer getCount() {
		return count;
	}
	 

	 public void setCount(Integer count) {
		this.count = count;
	}


	// 生产产品
	 public Integer makeProducts(){
		 // 产品内容我们暂时不关注啦,让数量增加,每单位时间生产1个
		return count ++;
	 }
	 
}

 

package com;

/**
 * 
 * 这是一个超市,相当于仓库
 *
 */
public class SuperMarket {
    // 超市 也需要知道存放的数量
	private Integer count;
	// 超市最大存放的数量
	public static final Integer MAX_COUNT = 100;
	
	// 肯定有一个卖东西 出去的方法
	public void sendProducts(Integer sendNum){
		count = count-sendNum;
	}
	
	// 查看超市的目前的产品数量
	public Integer getCount(){
		return count;
	}
	
	// 同时也有一个存货的方法,给超市添加货物嘛
	public void addProducts(Integer count){
		this.count = this.count+count;
	}
	
	// 我们要知道是否卖完了
	public boolean isEmpty(){
		return count <= 0?true:false;
	}
	
	// 同时要知道商品是否放满了,这里我们假设容量是100
	public boolean isFull(){
		return MAX_COUNT >= 0?true:false;
	}
}

 

   3.2 基本对象有了, 这里我还建立两个维护 生产者和超市,超市和顾客关系的对象。作用是把他们的行为独立出来。并且为了让 我们的生产者 超市  以及消费渠道唯一化,我暂时写死了我们的 类

 

   

package com;

/**
 * 
 * 假设这是关系渠道,假设生产者 和超市 只有一个
 *
 */
public class ShareObject {
	// 主要对象唯一,生产者 和超市 只有一个
	public static SuperMarket market = new SuperMarket();
	public static Producer producer = new Producer();
	
	// 关系买卖渠道唯一,不存在 da zha qiang(这几个字居然不允许提交) 之类的
	public static ProducMarket producAndMarket = new ProducMarket();
	public static CustomerMarket customerMarket = new CustomerMarket();
}

 

   

       

package com;

/**
 * 
 * 超市和生产者 之间肯定有联系
 * 一般情况有 进货 发货 等操作在这里进行
 * 
 */
public class ProducMarket {

	// 产品交易
	public Integer exchange(){
		// 看看生产生产了好多产品
		Integer total = ShareObject.market.getCount();
		System.out.println("生产者生产的产品数量为:"+total);
		
		// 超市把产品放进超市
		ShareObject.market.addProducts(total);
		System.out.println("超市现在拥有产品数量为:"+ShareObject.market.getCount());
		
		
		// 假设生产目前生产的东西全部都送到超市,然后数量就为0了,从新开始生产
		ShareObject.producer.setCount(0);
		return total;
	}
}

 

    

package com;

import java.util.Random;

/**
 * 
 * 顾客和超市之间肯定有关系嘛,
 * 这里也是买东西在这里进行
 *
 */
public class CustomerMarket {
	
	private SuperMarket market = ShareObject.market;
	
	
	// 顾客买东西
	public void buyProducts(){
		// 随机表示顾客买东西的数量 
		Random random = new Random();
		int num = random.nextInt(3);
		
		// 超市卖出去要少,这么多
		market.sendProducts(num);
		Customer c = new Customer();
		System.out.println("顾客:"+c.getName()+" 买走 "+num+" 个产品");
	}
}

 

 3.3 为了模拟整个操作,对 生产  超市进货 卖出  等,进行了线程管理

    

package com;

/**
 * 
 * 这是生产者的线程,控制生产这些状态
 * 相当于 厂家,需要一个管理晒
 *
 */
public class ProducerThread implements Runnable{

	// 生产率,假设1秒生产一个产品(有点快哈~。~)
	private static final Integer PRODUCT_TIME = 1000;

	@Override
	public void run() {
		// 假设是不间断生产
		while(true){
			// 工厂开始,开始生产产品
			ShareObject.producer.makeProducts();
			try {
				Thread.sleep(PRODUCT_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

 

package com;

/**
 * 
 * 超市的管理,这个主要负责超市进货
 *
 */
public class SuperMarketAddThread implements Runnable{

	// 进货的时间 10秒/次
	private static final Integer ADD_PRODUCT_TIME = 10000;
	@Override
	public void run() {
		// 这里我们假设 是24小时运营的超市,按时间进货
		while(true){
			try {
				// 进货那个对象操作
				ShareObject.producAndMarket.exchange();
				Thread.sleep(ADD_PRODUCT_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

 

package com;

/**
 * 
 * 超市的管理,这个主要负责超市售出 东西
 *
 */
public class SuperMarketSendThread implements Runnable{
	// 卖东西出去的时间 1秒
	private static final Integer SEND_TIME = 1000;
	@Override
	public void run() {
		// 这里我们假设 是24小时运营的超市
		while(true){
			try {
				// 顾客 和超市的类,操作方法 
				ShareObject.customerMarket.buyProducts();
				Thread.sleep(SEND_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

}

 

3.4 由于顾客 买东西, 和 超市卖出,我仅让超市 个 顾客的线程处理了,就没专门建立 顾客的线程。

package com;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 生产者   超市  顾客,先让他们存在
		Thread producter = new Thread(new ProducerThread());
		Thread marketAdd = new Thread(new SuperMarketAddThread());
		Thread marketSend = new Thread(new SuperMarketSendThread());
		
		// 顾客的的行为,我在SuperMarketSendThread 维护了
		// Thread customer = new Thread();
		
	        // 为了初始化,我先假设 生产者 已经生产了  50 产品
		// 超市里面 已经进货了 10个产品,不至于为空
		ShareObject.producer.setCount(50);
		ShareObject.market.addProducts(10);
		
		// 1. 逻辑上 我们应该先让生产者执行晒,毕竟要先生产产品嘛
		producter.start();
		// 2.然后是超市 
		marketAdd.start();
		// 3.然后才是消费者 来消费
		marketSend.start();
		// 虽然这么些,其实执行顺序是随机的。要加入队列才行,留在后面吧
                // 上面数量 ,可以将顾客买的数量随机数 改大,容易出现负数
                
	}

}

 

小结:

       1.上面是模拟了生产者消费者模型的实现,我们把 生产者,超市唯一化了。而实际情况要复杂很多。上面程序是有BUG的,因为没有考虑各种限制,2.变化 所列出的,都没考虑进去,留在后面进行了。

       2.整个程序设计是很初步的,有兴趣的童鞋,可以自己完善,后面我也会将常用的设计模式 融入进去,包括一个宏观设计,更加抽象,体验设计带来的乐趣。

       3.有啥批评建议的,尽管说,我脸皮厚,最喜欢大家的各种抨击,才能学习成长!

  • 大小: 8.5 KB
  • 大小: 33.6 KB
分享到:
评论

相关推荐

    Qt入门练习项目——生产者消费者模型.zip

    在本项目中,我们将使用Qt5的QThread类和信号与槽机制来实现生产者消费者模型。QThread类允许我们创建和管理独立的执行线程,而信号与槽是Qt的核心特性,用于在对象间传递消息和事件,这在多线程环境中尤其有用。 1...

    生产者与消费者实验报告

    3. **能够在多线程环境下实现简单的生产者与消费者模型,并对其性能进行分析**。 4. **学会分析和解决在多线程编程中常见的问题,如死锁、饥饿等**。 #### 四、实验环境与工具 - **操作系统**:Windows/Linux/Unix...

    C++实现生产与消费者模型

    在计算机科学中,生产者-消费者模型是一种经典的并发编程问题,用于解决多个线程之间如何高效、安全地共享资源的问题。在这个模型中,"生产者"线程负责生成数据,而"消费者"线程则负责处理这些数据。C++作为一门支持...

    生产者消费者多进程模型Qt

    在IT领域,生产者消费者模型是一种经典的并发编程模式,它源于操作系统理论,用于解决资源的高效利用和同步问题。在本案例中,该模型被应用于一个使用Qt框架开发的多进程环境中,使得生产者进程与消费者进程能有效地...

    java生产者消费者模型

    5. **设计模式**:生产者消费者模型可以看作是一种“生产者-消费者”设计模式的实例,它属于行为设计模式,用于协调异步处理和共享资源。此外,还可以结合观察者模式,让消费者订阅生产者,当有新数据时,生产者通知...

    使用Qt信号量实现单生产者多消费者模型

    在多线程编程中,设计模式是解决特定问题的有效手段,其中之一便是生产者-消费者模型。这个模型描述了两个或多个线程之间的协作,其中一方(生产者)生成数据,另一方(消费者)消费这些数据。在Qt框架下,我们可以...

    自己用Java写的简单生产者与消费者模型

    在Java编程中,生产者-消费者模型是一...总的来说,这个简单的生产者-消费者模型是学习和理解Java多线程编程的一个良好起点。通过这种方式,你可以更好地掌握如何在Java中创建并发程序,解决数据共享和资源调度的问题。

    labview 生产者消费者例子

    总之,LabVIEW 生产者-消费者模型是解决多线程同步问题的有效工具,它通过队列、事件结构、条件变量和信号量等手段,协调了数据生成与处理的过程,提高了系统的并发性和效率。通过学习和实践提供的例程,可以进一步...

    多个消费者生产者模型

    首先,我们要理解"生产者-消费者模型"的基本原理。在计算机科学中,这通常通过使用队列(Queue)数据结构实现。队列是一种先进先出(FIFO)的数据结构,生产者在队列的一端放入产品,消费者则在另一端取出产品。当...

    生产者消费者模型的演变

    生产者消费者模型是一种多线程同步的经典设计模式,它源于操作系统中的进程通信概念,用于解决资源的高效利用和协同工作问题。在这个模型中,生产者线程负责生成数据,而消费者线程则负责消费这些数据。为了确保生产...

    java生产者与消费者实验报告

    本实验旨在通过实际编程操作,深入理解Java中生产者与消费者模型的工作机制及其同步控制策略,具体目标为实现多生产者与多消费者之间的数据共享和线程同步。 #### 实验原理 生产者-消费者模型主要涉及到以下概念:...

    jchc.rar_tearshmj_生产者_生产者-消费者问题 c++ _生产者和消费者_生产者消费者

    首先,我们要理解生产者-消费者模型的基本概念。在这个模型中,生产者负责生产资源,而消费者则负责消耗这些资源。关键在于,生产者和消费者必须以一种协调的方式工作,以免出现资源过度消费或生产过剩的情况。这就...

    生产者与消费者问题 操作系统课程设计

    本课程设计旨在帮助学生深入理解进程间的同步机制,并通过实际编程来实现生产者-消费者模型。具体目标包括: - **理解进程同步**:深入学习生产者-消费者模型及其同步规则。 - **熟悉开发工具**:熟练使用Visual ...

    生产者消费者为模型的多线程编程c#原创

    在C#编程中,"生产者消费者模型"是一种常见的多线程设计模式,它通过分离数据的生产和消费过程,使得生产者线程可以专心于创建数据,而消费者线程则专注于处理这些数据,两者互不干扰,提高了系统效率。在这个模型中...

    消费者生产者模型 c++

    ### 消费者生产者模型 C++ #### 一、代码概览 此代码段实现了一个典型的消费者生产者模型,利用 C++ 和 Windows API 进行线程管理和同步控制。主要功能包括: - 定义了一个最大缓冲区数量 (`MAX_BUFFER_NUM`) 为 ...

    课程设计之生产者与消费者 java语言编写

    3. **BlockingQueue的使用**:在生产者与消费者模型中,`BlockingQueue`充当数据缓冲区的角色。生产者将数据放入队列,消费者从队列中取出数据。队列的`put()`方法会在队列满时阻塞生产者,`take()`方法会在队列空时...

    生产者消费者问题 MFC

    生产者消费者问题是多线程编程中的一个经典案例,它展示了如何通过共享资源在并发环境中实现线程间的协调。在这个问题中,"生产者"线程负责生成数据,而"消费者"线程则负责消费这些数据。MFC(Microsoft Foundation ...

    linux进程链、进程扇和信号量实现生产者--消费者模型实验报告

    实验报告 一、实验目的 本实验旨在深入理解Linux操作系统中的核心进程概念,包括进程...同时,对于生产者-消费者模型的实现,加深了对资源管理和并发访问控制的理解,提升了在Linux环境中编写和调试多进程程序的能力。

    操作系统实验之进程的互斥与同步(生产者与消费者问题)VC++

    例如,在生产者与消费者问题中,有一个缓冲区作为共享资源,生产者将产品放入缓冲区,而消费者则从缓冲区取出产品。为了保证数据的一致性,必须确保在任何时候,缓冲区要么只允许一个生产者写入,要么只允许一个消费...

    Java线程间的通信----生产者消费者模型

    通过理解并熟练掌握生产者消费者模型,开发者可以有效地设计出高效、稳定的并发程序,提高系统资源利用率,并降低线程之间的竞争。在实际项目中,生产者消费者模型被广泛应用于缓存管理、数据库批量操作、消息队列等...

Global site tag (gtag.js) - Google Analytics