JAVA - 多线程 - 生产者与消费者
2015-10-19 19:12
429 查看
生产者消费者模型
生产者线程:能够生产两种产品(中文、英文),生产者产出信息后将其放到一个区域之中;消费者线程:不停的从区域中取走生产者生产出来的产品;
产品的生产是需要耗费一定时间的。
基本实现
定义一个产品类Product,作为产品存放区;定义Productor线程,生产产品;
定义Consumer线程,取走产品。
//产品 class Product { private String name = "苹果"; private String content = "爱疯"; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } //生产者线程 class Productor implements Runnable { private Product product = null; public Productor(Product product){ this.product = product; } public void run() { boolean flag = true; //控制生产哪种产品 for(int i = 0; i < 50; i++) { if(flag) { //如果flag是TRUE,生产第一种产品 this.product.setName("苹果"); try { //线程休眠,模拟生产需要时间 Thread.sleep(90); } catch (Exception e) { e.printStackTrace(); } this.product.setContent("爱疯"); flag = false; } else { this.product.setName("Apple"); try { Thread.sleep(90); } catch (Exception e) { e.printStackTrace(); } this.product.setContent("Iphone"); flag = true; } } } } //消费者线程 class Consumer implements Runnable { private Product product = null; public Consumer(Product product) { this.product = product; } public void run() { for(int i = 0; i < 50; i++) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } System.out.println(this.product.getName() + " ----> " + this.product.getContent()); //取走产品 } } } //MAIN函数 public class ProductorConsumerDemo { public static void main(String[] args) { Product product = new Product(); //产品存放区 Productor productor = new Productor(product); Consumer consumer = new Consumer(product); new Thread(productor).start(); //启动生产者线程,生产产品 new Thread(consumer).start(); //启动消费者线程,取走产品 } }
运行结果:
Apple ----> 爱疯 苹果 ----> Iphone Apple ----> 爱疯 苹果 ----> 爱疯 Apple ----> Iphone Apple ----> Iphone Apple ----> Iphone Apple ----> Iphone Apple ----> Iphone Apple ----> Iphone
存在的问题
中文产品与英文产品的信息混在一起:原因是因为生产需要一定的时间,当生产者线程中一种产品还没生产完就切换到消费者线程,解决方案是生产者线程在生产的时候需要加入同步操作;生产者生产了若干个产品,消费者才开始取走产品:原因是生产者线程在休眠的时候,消费者线程重复取走产品,解决方案是加入等待唤醒机制。
问题的解决
将Product类生产和读取封装成不同的方法,并将其设置为同步方法;在生产和消费方法中加入等待唤醒机制,生产方法需要等待消费方法取走产品后的通知才能继续生产,消费方法需要等待生产方法生产完成通知后才能继续取走。
代码实现:
//产品 class Product { private String name = "苹果"; private String content = "爱疯"; private boolean flag = false; //是否可取走产品的标志位,TRUE可取走,FALSE可生产 //封装生产方法 public synchronized void set(String name, String content) { //同步方法解决问题一 if(!flag) { try { super.wait(); //生产者线程等待,线程等待唤醒解决问题二 } catch (Exception e) { e.printStackTrace(); } } this.setName(name); try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace(); } this.setContent(content); flag = false; super.notify(); //唤醒消费者线程 } //封装消费方法 public synchronized void get() { if(flag) { try { super.wait(); } catch (Exception e) { e.printStackTrace(); } } try { Thread.sleep(300); } catch (Exception e) { e.printStackTrace(); } System.out.println(this.getName() + " ----> " + this.getContent()); //取走产品 flag = true; super.notify(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } } //生产者线程 class Productor implements Runnable { private Product product = null; public Productor(Product product){ this.product = product; } public void run() { boolean flag = true; //控制生产哪种产品 for(int i = 0; i < 50; i++) { if(flag) { //如果flag是TRUE,生产第一种产品 this.product.set("苹果", "爱疯"); flag = false; } else { this.product.set("Apple", "Iphone"); flag = true; } } } } //消费者线程 class Consumer implements Runnable { private Product product = null; public Consumer(Product product) { this.product = product; } public void run() { for(int i = 0; i < 50; i++) { try { Thread.sleep(100); } catch (Exception e) { e.printStackTrace(); } this.product.get(); } } } //MAIN函数 public class ProductorConsumerDemo { public static void main(String[] args) { Product product = new Product(); //产品存放区 Productor productor = new Productor(product); Consumer consumer = new Consumer(product); new Thread(productor).start(); //启动生产者线程,生产产品 new Thread(consumer).start(); //启动消费者线程,取走产品 } }
BR~
Jianwei Wang
相关文章推荐
- 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简单理解
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树