文档章节

多线程中的生产者,消费者问题

Zero零_度
 Zero零_度
发布于 2015/07/30 10:43
字数 551
阅读 5
收藏 0

卖饭类:

package com.sniper.thread.lock.domain;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * 餐馆,负责卖饭
 * @author sniper
 *
 */
public class Restaurant implements Runnable {
 
 public void sale() {
  while(true) {
   synchronized (Window.class) {
    List<Food> foods = Window.foods;
    if(foods.size() > 0) {
     Food food = foods.get(0);
     System.out.println(Thread.currentThread().getName() + "卖了第" + food.getId() + "号食物。。。");
     
     /*try {
      TimeUnit.SECONDS.sleep(1);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }*/
     
     //卖出一份,减少一份
     foods.remove(0);
     
     //Window.class.notify();//随机唤醒等待中的一条线程
     Window.class.notifyAll();//唤醒等待中全部线程
    } else {
     System.out.println(Thread.currentThread().getName() + ":食物卖完了,我休息了。。。");
     
     try {
      Window.class.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
  }
 }
 @Override
 public void run() {
  sale();
 }
 
}

做饭类:

package com.sniper.thread.lock.domain;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
 * 厨师,负责做饭
 * @author sniper
 *
 */
public class Cook implements Runnable {
 
 public static int num = 1;
 
 public void make() {
  while(true) {
   synchronized (Window.class) {
    List<Food> foods = Window.foods;
    if(foods.size() <= Window.max_num) {
     Food food = new Food(num);
     foods.add(food);
     
     System.out.println(Thread.currentThread().getName() + "做了第" + food.getId() + "号食物。。。");
     
     
     /*try {
      TimeUnit.SECONDS.sleep(1);
     } catch (InterruptedException e) {
      e.printStackTrace();
     }*/
     
     num++;
     
     /*
      * notify随机唤醒一条线程,容易产生问题
      * 假设三个做饭的,三个卖饭的
      * 在某一瞬间三个卖饭的都处于等待,两个做饭的也处于等待
      * 最后一个做饭的做好一份饭之后,随机唤醒其中一条,假如唤醒的是做饭线程,
      * 此时,两条醒着的做饭线程判断foods.size() > Window.max_num(1)
      * 然后两条做饭线程也休息了,此时,六条线程都会处于等待状态,没人会唤醒他们
      * 也就是死锁
      */
     //Window.class.notify();//随机唤醒等待中的一条线程
     Window.class.notifyAll();//唤醒等待中全部线程
    } else {
     System.out.println(Thread.currentThread().getName() + ":窗口放满食物了,我休息了。。。");
     try {
      Window.class.wait();
     } catch (InterruptedException e) {
      e.printStackTrace();
     }
    }
   }
  }
 }
 @Override
 public void run() {
  make();
 }
 
}

窗口,从窗口取饭卖,做完饭往窗口放:

package com.sniper.thread.lock.domain;
import java.util.ArrayList;
import java.util.List;
/**
 * 窗口,厨师做完饭往窗口放,餐馆从窗口拿饭卖
 * @author sniper
 *
 */
public class Window {
 
 public static List<Food> foods = new ArrayList<Food>();
 
 //窗口最大容纳食物数量
 public static int max_num = 1;
 
}

食物类:

package com.sniper.thread.lock.domain;
/**
 * 食物
 * @author sniper
 *
 */
public class Food {
 
 private int id;
 
 private String name;
 public Food(int id) {
  super();
  this.id = id;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 
}

App:

package com.sniper.thread.lock.domain;
public class App {
 
 public static void main(String[] args) {
  Cook cook = new Cook();
  //三条做饭线程
  for(int i=0; i<3; i++) {
   new Thread(cook).start();
  }
  
  Restaurant r = new Restaurant();
  //十条卖饭线程
  for(int i=0; i<3; i++) {
   new Thread(r).start();
  }
 }
 
}

© 著作权归作者所有

Zero零_度
粉丝 69
博文 1267
码字总数 263854
作品 0
程序员
私信 提问
C#多线程学习(三) 生产者和消费者

[1] C#多线程学习(三) 生产者和消费者 [2]C#多线程学习(三) 生产者和消费者 本系列文章导航 C#多线程学习(一) 多线程的相关概念 C#多线程学习(二) 如何操纵一个线程 C#多线程学习(三) 生产者...

Yamazaki
2012/03/29
19
0
一篇文章理清Python多线程之同步条件,信号量和队列

公众号:pythonislover 今天这篇文章大概介绍下python多线程中的同步条件Event,信号量(Semaphore)和队列(queue),这是我们多线程系列的最后一篇文章,以后将会进入python多进程的系列。 同步...

南山yrg
04/30
0
0
秒杀多线程第十篇 生产者消费者问题

继经典线程同步问题之后,我们来看看生产者消费者问题及读者写者问题。生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去...

长平狐
2012/12/10
73
0
生产者/消费者问题的多种Java实现方式

生产者消费者问题是研究多线程程序时绕不开的经典问题之一,它描述是有一块缓冲区作为仓库,生产者可以将产品放入仓库,消费者则可以从仓库中取走产品。解决生产者/消费者问题的方法可分为两...

HenrySun
2016/05/04
92
0
秒杀多线程第十篇 生产者消费者问题

继经典线程同步问题之后,我们来看看生产者消费者问题及读者写者问题。生产者消费者问题是一个著名的线程同步问题,该问题描述如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去...

晨曦之光
2012/05/21
128
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot2.0 maven打包分离lib,resources

springboot将工程打包成jar包后,会出现获取classpath下的文件出现测试环境正常而生产环境文件找不到的问题,这是因为 1、在调试过程中,文件是真实存在于磁盘的某个目录。此时通过获取文件路...

陈俊凯
今天
5
0
BootStrap

一、BootStrap 简洁、直观、强悍的前端开发框架,让web开发更加迅速、简单 中文镜像网站:http://www.bootcss.com 用于开发响应式布局、移动设备优先的WEB项目 1、使用boot 创建文件夹,在文...

wytao1995
今天
9
0
小知识:讲述Linux命令别名与资源文件的区别

别名 别名是命令的快捷方式。为那些需要经常执行,但需要很长时间输入的长命令创建快捷方式很有用。语法是: alias ppp='ping www.baidu.com' 它们并不总是用来缩短长命令。重要的是,你将它...

老孟的Linux私房菜
今天
8
0
《JAVA核心知识》学习笔记(6. Spring 原理)-5

它是一个全面的、企业应用开发一站式的解决方案,贯穿表现层、业务层、持久层。但是 Spring 仍然可以和其他的框架无缝整合。 6.1.1. Spring 特点 6.1.1.1. 轻量级 6.1.1.2. 控制反转 6.1.1....

Shingfi
今天
7
0
Excel导入数据库数据+Excel导入网页数据【实时追踪】

1.Excel导入数据库数据:数据选项卡------>导入数据 2.Excel导入网页数据【实时追踪】:

东方墨天
今天
10
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部