新建一个Break类,表示食物数量。

public class Break {
public static final int MAX = 10; //最多一次性煮十个面包
Stack<Integer> stack = new Stack<Integer>();
public static int food_count = 0; //统计食物的个数 //做面包
public synchronized void make_food(int number){
stack.push(number);
food_count++;
} //吃食物
public synchronized int eat_food(){
food_count--;
return stack.pop();
}
}

  在创建一个厨房类,为了制作食物或者是消耗食物,若食物没有了,则消费者进入wait(),生产者开始制作食物,随后唤醒等待的消费者。

public class Kitchen {
private Break food ;
public static int people1_eatnumber = 0;//第一个人吃的面包数量
public static int people2_eatnumber = 0;//第二个人吃的面包数量
public static final int TOTOAL_NUM = 100;//总共做的面包数量
public static int icount = 1;//统计做过的面包数量 public Kitchen(Break food){
this.food = food;
} //做面包的方法
public synchronized void make(){
if(food.food_count<10){//锅是不是满了
food.make_food(Kitchen.icount);
System.out.println("做完了第"+Kitchen.icount+"个食物。");
Kitchen.icount++;
notifyAll();//食物有了,找两个人来吃面包
}else{
System.out.println("锅已经装满,一次性装十个,等待两人吃食物。");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}//进入阻塞状态,等待消费者唤醒
}
} //吃面包的方法
public synchronized void eat(){
if(food.food_count>0){
int temp = food.eat_food();//吃掉面包的编号
System.out.println(Thread.currentThread().getName()+"吃掉了第"+temp+"个食物");
if(Thread.currentThread().getName().equals("一号")){
people1_eatnumber++;
}else{
people2_eatnumber++;
}
notifyAll(); //唤醒继续做面包
}else{
System.out.println("食物吃完了,等待重新烹饪。");
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

  下面进入消费者和生产者类的构造,传递给一个Kitchen对象,其中消费者调用Kitchen类中的吃方法。

public class consumer implements Runnable {
Kitchen kitchen; public consumer(Kitchen kitchen){
this.kitchen = kitchen;
} @Override
public void run() {
// TODO Auto-generated method stub
while(true){
if(kitchen.icount>100&&Break.food_count<=0){
break;
}
try{
kitchen.eat();
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
}
}
}

  然而生产者则是调用了Kitchen对象中的制作方法。

public class product implements Runnable {
private Kitchen kitchen;
public product(Kitchen kitchen){
this.kitchen = kitchen;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
//结束这个线程
if(Kitchen.icount > 100){
break;
}
try{
kitchen.make();
Thread.sleep(100);
}catch(Exception e){
e.printStackTrace();
}
}
System.out.println("厨房食物材料已经做完。");
}
}

  下面开始写主类,包括了main方法,启动程序,创建一个test类,实现:

public class test {
public static void main(String[] args){
Break brake = new Break();
Kitchen kitchen = new Kitchen(brake);
product p = new product(kitchen);
consumer c1 = new consumer(kitchen);
consumer c2 = new consumer(kitchen); Thread food = new Thread(p,"食物");
Thread people1 = new Thread(c1,"一号");
Thread people2 = new Thread(c2,"二号"); food.start();
people1.start();
people2.start(); try{
food.join();
people1.join();
people2.join();
}catch(Exception e){
e.printStackTrace();
} System.out.println("一号吃了"+Kitchen.people1_eatnumber);
System.out.println("二号吃了"+Kitchen.people2_eatnumber);
}
}

输出结果如下:

做完了第1个食物。
二号吃掉了第1个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第2个食物。
一号吃掉了第2个食物
食物吃完了,等待重新烹饪。
做完了第3个食物。
一号吃掉了第3个食物
食物吃完了,等待重新烹饪。
做完了第4个食物。
一号吃掉了第4个食物
做完了第5个食物。
二号吃掉了第5个食物
食物吃完了,等待重新烹饪。
做完了第6个食物。
二号吃掉了第6个食物
食物吃完了,等待重新烹饪。
做完了第7个食物。
二号吃掉了第7个食物
做完了第8个食物。
一号吃掉了第8个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第9个食物。
一号吃掉了第9个食物
食物吃完了,等待重新烹饪。
做完了第10个食物。
一号吃掉了第10个食物
做完了第11个食物。
二号吃掉了第11个食物
食物吃完了,等待重新烹饪。
做完了第12个食物。
二号吃掉了第12个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第13个食物。
一号吃掉了第13个食物
做完了第14个食物。
二号吃掉了第14个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第15个食物。
一号吃掉了第15个食物
做完了第16个食物。
二号吃掉了第16个食物
食物吃完了,等待重新烹饪。
做完了第17个食物。
二号吃掉了第17个食物
食物吃完了,等待重新烹饪。
做完了第18个食物。
二号吃掉了第18个食物
食物吃完了,等待重新烹饪。
做完了第19个食物。
二号吃掉了第19个食物
食物吃完了,等待重新烹饪。
做完了第20个食物。
二号吃掉了第20个食物
食物吃完了,等待重新烹饪。
做完了第21个食物。
二号吃掉了第21个食物
食物吃完了,等待重新烹饪。
做完了第22个食物。
二号吃掉了第22个食物
食物吃完了,等待重新烹饪。
做完了第23个食物。
二号吃掉了第23个食物
食物吃完了,等待重新烹饪。
做完了第24个食物。
二号吃掉了第24个食物
食物吃完了,等待重新烹饪。
做完了第25个食物。
二号吃掉了第25个食物
食物吃完了,等待重新烹饪。
做完了第26个食物。
二号吃掉了第26个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第27个食物。
一号吃掉了第27个食物
食物吃完了,等待重新烹饪。
做完了第28个食物。
一号吃掉了第28个食物
食物吃完了,等待重新烹饪。
做完了第29个食物。
一号吃掉了第29个食物
做完了第30个食物。
二号吃掉了第30个食物
食物吃完了,等待重新烹饪。
做完了第31个食物。
二号吃掉了第31个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第32个食物。
一号吃掉了第32个食物
食物吃完了,等待重新烹饪。
做完了第33个食物。
一号吃掉了第33个食物
食物吃完了,等待重新烹饪。
做完了第34个食物。
一号吃掉了第34个食物
做完了第35个食物。
二号吃掉了第35个食物
食物吃完了,等待重新烹饪。
做完了第36个食物。
二号吃掉了第36个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第37个食物。
一号吃掉了第37个食物
食物吃完了,等待重新烹饪。
做完了第38个食物。
一号吃掉了第38个食物
食物吃完了,等待重新烹饪。
做完了第39个食物。
一号吃掉了第39个食物
做完了第40个食物。
二号吃掉了第40个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第41个食物。
一号吃掉了第41个食物
做完了第42个食物。
二号吃掉了第42个食物
做完了第43个食物。
二号吃掉了第43个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第44个食物。
一号吃掉了第44个食物
食物吃完了,等待重新烹饪。
做完了第45个食物。
一号吃掉了第45个食物
做完了第46个食物。
二号吃掉了第46个食物
食物吃完了,等待重新烹饪。
做完了第47个食物。
二号吃掉了第47个食物
食物吃完了,等待重新烹饪。
做完了第48个食物。
二号吃掉了第48个食物
食物吃完了,等待重新烹饪。
做完了第49个食物。
二号吃掉了第49个食物
食物吃完了,等待重新烹饪。
做完了第50个食物。
二号吃掉了第50个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第51个食物。
一号吃掉了第51个食物
食物吃完了,等待重新烹饪。
做完了第52个食物。
一号吃掉了第52个食物
做完了第53个食物。
二号吃掉了第53个食物
做完了第54个食物。
一号吃掉了第54个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第55个食物。
做完了第56个食物。
二号吃掉了第56个食物
一号吃掉了第55个食物
做完了第57个食物。
一号吃掉了第57个食物
食物吃完了,等待重新烹饪。
做完了第58个食物。
一号吃掉了第58个食物
做完了第59个食物。
二号吃掉了第59个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第60个食物。
一号吃掉了第60个食物
做完了第61个食物。
二号吃掉了第61个食物
食物吃完了,等待重新烹饪。
做完了第62个食物。
二号吃掉了第62个食物
食物吃完了,等待重新烹饪。
做完了第63个食物。
二号吃掉了第63个食物
食物吃完了,等待重新烹饪。
做完了第64个食物。
二号吃掉了第64个食物
食物吃完了,等待重新烹饪。
做完了第65个食物。
二号吃掉了第65个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第66个食物。
做完了第67个食物。
二号吃掉了第67个食物
一号吃掉了第66个食物
做完了第68个食物。
一号吃掉了第68个食物
食物吃完了,等待重新烹饪。
做完了第69个食物。
一号吃掉了第69个食物
食物吃完了,等待重新烹饪。
做完了第70个食物。
一号吃掉了第70个食物
做完了第71个食物。
二号吃掉了第71个食物
食物吃完了,等待重新烹饪。
做完了第72个食物。
二号吃掉了第72个食物
食物吃完了,等待重新烹饪。
做完了第73个食物。
二号吃掉了第73个食物
食物吃完了,等待重新烹饪。
食物吃完了,等待重新烹饪。
做完了第74个食物。
一号吃掉了第74个食物
食物吃完了,等待重新烹饪。
做完了第75个食物。
一号吃掉了第75个食物
做完了第76个食物。
二号吃掉了第76个食物
食物吃完了,等待重新烹饪。
做完了第77个食物。
二号吃掉了第77个食物
食物吃完了,等待重新烹饪。
做完了第78个食物。
二号吃掉了第78个食物
食物吃完了,等待重新烹饪。
做完了第79个食物。
二号吃掉了第79个食物
食物吃完了,等待重新烹饪。
做完了第80个食物。
二号吃掉了第80个食物
食物吃完了,等待重新烹饪。
做完了第81个食物。
二号吃掉了第81个食物
食物吃完了,等待重新烹饪。
做完了第82个食物。
二号吃掉了第82个食物
食物吃完了,等待重新烹饪。
做完了第83个食物。
二号吃掉了第83个食物
食物吃完了,等待重新烹饪。
做完了第84个食物。
二号吃掉了第84个食物
食物吃完了,等待重新烹饪。
做完了第85个食物。
二号吃掉了第85个食物
食物吃完了,等待重新烹饪。
做完了第86个食物。
二号吃掉了第86个食物
食物吃完了,等待重新烹饪。
做完了第87个食物。
二号吃掉了第87个食物
食物吃完了,等待重新烹饪。
做完了第88个食物。
二号吃掉了第88个食物
做完了第89个食物。
二号吃掉了第89个食物
食物吃完了,等待重新烹饪。
做完了第90个食物。
二号吃掉了第90个食物
食物吃完了,等待重新烹饪。
做完了第91个食物。
二号吃掉了第91个食物
食物吃完了,等待重新烹饪。
做完了第92个食物。
二号吃掉了第92个食物
食物吃完了,等待重新烹饪。
做完了第93个食物。
二号吃掉了第93个食物
食物吃完了,等待重新烹饪。
做完了第94个食物。
二号吃掉了第94个食物
食物吃完了,等待重新烹饪。
做完了第95个食物。
二号吃掉了第95个食物
食物吃完了,等待重新烹饪。
做完了第96个食物。
二号吃掉了第96个食物
食物吃完了,等待重新烹饪。
做完了第97个食物。
二号吃掉了第97个食物
食物吃完了,等待重新烹饪。
做完了第98个食物。
二号吃掉了第98个食物
食物吃完了,等待重新烹饪。
做完了第99个食物。
二号吃掉了第99个食物
食物吃完了,等待重新烹饪。
做完了第100个食物。
二号吃掉了第100个食物
厨房食物材料已经做完。
一号吃了33
二号吃了67

Java程序设计之消费者和生产者的更多相关文章

  1. [Java基础] java多线程关于消费者和生产者

    多线程: 生产与消费 1.生产者Producer生产produce产品,并将产品放到库存inventory里:同时消费者Consumer从库存inventory里消费consume产品. 2.库存in ...

  2. java 模拟实现消费者和生产者问题

    题目要求 用java代码模拟实现:一个人不断往箱子里放苹果,另一个人不断从箱子里取苹果,箱子只能放5个苹果,苹果数量无限.要求不使用java.util.concurrent包中的类. 思路 这道题主要 ...

  3. Java笔记1 : 在生产者消费者模式中,线程通信与共享数据,死锁问题与解决办法

    本例定义了4个类,这里说一下,方便下面讲解.分别是Product(产品),Producer(生产者),Consumer(消费者), Test(测试类). 多线程之间通信与共享数据只要引用同一内存区域就 ...

  4. java线程之多个生产者消费者2.0

    上一节中,通过while和notifyAll解决了多个生产者,消费者对共享资源的访问问题,现在开始升级 但是,仍然有改进之处,主要体现在两点: 1)使用新版本1.5开始后的锁Lock解决,目的将其全部 ...

  5. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

  6. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  7. java并发:初探消费者和生产者模式

    消费者和生产者模式 用继承Thread方式,用wait和notifyAll方法实现. 消费者和生产者模式的特点 1. 什么时候生产:仓库没有满的时候,生产者这可以生产,消费者也可以消费,仓库满的时候停 ...

  8. java多线程-消费者和生产者模式

    /* * 多线程-消费者和生产者模式 * 在实现消费者生产者模式的时候必须要具备两个前提,一是,必须访问的是一个共享资源,二是必须要有线程锁,且锁的是同一个对象 * */ /*资源类中定义了name( ...

  9. Java多线程消费者、生产者的基本思路

    多线程主要考察的就是 线程的同步控制   生产者消费者的思路就是,当 一个线程执行时让另一个线程 挂起就行了 ThreadOne.ThreadTwo同时运行,添加一个变量在一个公共类(下边的Funct ...

随机推荐

  1. Bootstrap之表单控件状态

    Bootstrap中的表单控件状态主要有三种:焦点状态,禁用状态,验证状态.   一.焦点状态:该状态告诉用户可输入或选择东西 焦点状态通过伪类“:focus”以实现. bootstrap.css相应 ...

  2. Lind.DDD.IoC依赖注入与面向方面的实现

    回到目录 IoC是解耦的灵魂,很难想像一个框架中没有IoC会变成什么样子,Lind.DDD里的IoC是通过Unity实现的,由依赖注入(unity)和方法拦截组成(Interception),依赖注入 ...

  3. Netty(四)分隔符与定长解码器的使用

    TCP以流的形式进行数据传输,上层的应用协议为了对消息进行划分,往往采用如下的4种方式. (1)消息长度固定,累计读到长度总和为定长len的报文后,就认为读取到了一个完整的消息:然后重新开始读取下一个 ...

  4. e.target.files[0]层层剖析

    因为我现在拿到的一个功能是上传时过滤掉很大尺寸的图片,所以需要来拿到上传时选择图片的size,所以有了这篇博文 不多说 上代码 $('input').change(function(e){ 1️⃣.c ...

  5. HTML5移动端图片左右切换动画

    插件描述:HTML5移动端图片左右切换动画 小海今天要给大家分享一款很不错的图片左右切换焦点图动画,并且支持移动端触摸滑动.功能上,这款HTML5图片播放器支持鼠标滑动.手机端触摸滑动以及自动播放.外 ...

  6. 独立IP 与 共享IP

    最近在阿里云产品体系中折腾的不亦乐乎,在选则服务器的时候,会有独立IP和共享IP的两种不同的选择,这里查阅资料予以记录,独立IP与共享IP的区别: 因为IP资源有限,独立IP就是说一个IP地址只给你一 ...

  7. 轻松掌握:JavaScript策略模式

    策略模式 定义:定义一系列的算法,把它们一个个封装成函数,也可把它们作为属性统一封装进一个对象,然后再定义一个方法,该方法可根据参数自动选择执行对应的算法. 一般用于在实现一个功能时,有很多个方案可选 ...

  8. iOS更改tabbar图片渲染 —不让tabbat有蓝色的渲染 并修改文字

    方式一  代码实现 这种要写很多代码 ,每个控制器都要写   UIImage *image=[UIImage imageNamed:@"tabBar_friendTrends_click_i ...

  9. 比Ansible更吊的自动化运维工具,自动化统一安装部署自动化部署udeploy 1.0 版本发布

    新增功能: 逻辑与业务分离,完美实现逻辑与业务分离,业务实现统一shell脚本开发,由框架统一调用. 并发多线程部署,不管多少台服务器,多少个服务,同时发起线程进行更新.部署.启动. 提高list规则 ...

  10. Linux system log avahi-daemon[3733]: Invalid query packet

    在检查Linux的日志文件时,发现大量 avahi-daemon[3733]: Invalid query packet错误(不同服务器对应的数字有所不同) Aug  3 07:00:01 hostn ...