Java多线程与并发(五)之生产者与消费者案例
2016-05-13 09:22
441 查看
生产者与消费者应用案例
多线程的开发中有一个经典的操作案例,就是生产者-消费者,生产者不断生产产品,消费者不断取走产品。例如: 饭店里的有一个厨师和一个服务员,这个服务员必须等待厨师准备好膳食。当厨师准备好时,他会通知服务员,之后服务员上菜,然后返回继续等待。这是一个任务写作的示例,厨师代表生产者,而服务员代表消费者。
首先我们需要创建相应的类:
生产者类, 用于生产产品(我们这里的产品指的是Food,该类在下面展示)
假设我们生产的食物有两种”重庆小面”和”糖醋里脊”,
// 生产者类 class Producter implements Runnable { private Food food; public Producter(Food food) { this.food = food; } @Override public void run() { for (int i = 0; i < 50; i++) { if (i % 2 == 0) { food.set("重庆小面", "就是好吃!!!"); } else { // 是奇数的时候 food.set("糖醋里脊", "酸甜可口!"); } } } }
消费者类,也就是消费食物
// 消费者类 class Customer implements Runnable { private Food food; public Customer(Food food) { this.food = food; } @Override public void run() { for (int i = 0; i < 50; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } food.get(); } } }
消费和生产的对象, 食物类,这是我们的核心类, 同步代码在该类中体现.
注:在这里就用到了我在之前博客中提到的wait()方法和notify()方法,简单说明一下:
1. wait方法表示当前线程进入等待状态,会让出CPU并释放该监视器上的锁,但是要注意跟sleep方法的区别,sleep方法执行后是不会让出锁的,代码中执行了wait方法后会一直等待被“唤醒”, 也就是notify方法
2. notify方法, 用来唤醒已等待的方法,还有一个notifyAll方法,区别在于前者只唤醒其中一个,而后者则唤醒全部
// 消费的对象(数据), 食物类 class Food { private String name;//菜名 private String efficacy;//功效 // true表示可以生产 false表示可以消费 private boolean flag = true; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEfficacy() { return efficacy; } public void setEfficacy(String efficacy) { this.efficacy = efficacy; } public Food(String name, String efficacy) { super(); this.name = name; this.efficacy = efficacy; } // 生产产品 public synchronized void set(String name, String efficacy) { // System.out.println("重庆小面"); // 表示不能生产,但是可以消费,需要把时间让出啦 if (!flag) { try { // 等待跟休眠不同,sleep会进入等待但是不会让出锁 this.wait();// 表示当前线程进入等待状态,会让出CPU并释放该监视器上的锁 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } this.setName(name); try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } this.setEfficacy(efficacy); // 生产完成后 flag = false; this.notify();// 唤醒该监视器上的其他线程(只是唤醒一个) } public synchronized void get() { if (flag) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(this.getName() + "->" + this.getEfficacy()); this.notify(); flag = true; } public Food() { } }
测试类
public class ThreadDemo4 { public static void main(String[] args) { Food food = new Food(); Producter p = new Producter(food); Customer c = new Customer(food); Thread t1 = new Thread(p); Thread t2 = new Thread(c); t1.start(); t2.start(); } }
代码执行结果:
以上纯属个人见解, 如有不足之处希望有高人指出, 定感激不尽, 如有喜欢交流学习经验请给我留言谢谢.
原创文章, 转载请注明出处
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序