多线程模拟生产者和消费者模型
2016-05-27 11:18
429 查看
模拟生产者一边生产数据,消费者一边取出数据, 但以下代码会出现数据错位现象和重复生产,不符合我们的要求 package com.wzy.java8.thread; class Info{ private String title; private String content; public void setContent(String content) { this.content = content; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public String getTitle() { return title; } } class Productor implements Runnable{ private Info info = null; public Productor(Info info){ this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { if(i%2 == 0) { this.info.setTitle("偶数"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是偶数"); }else{ this.info.setTitle("奇数"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是奇数"); } } } } class Consumers implements Runnable{ private Info info = null; public Consumers(Info info) { this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(info.getTitle()+" "+info.getContent()); } } } public class Demo2 { public static void main(String[] args) { Info info = new Info(); Productor p = new Productor(info); Consumers c = new Consumers(info); new Thread(p).start(); new Thread(c).start(); } }
奇数 这是偶数 偶数 这是奇数 奇数 这是偶数 偶数 这是奇数 奇数 这是偶数
使用同步synchronized可以解决数据错位问题
使用super.wait(),super.notify();可以解决重复生产问题
思路:对于生产者:如果不可以生产,就休眠,等待正在取数据的消费者唤醒,被唤醒后,再生产,生产完成后唤醒消费者;消费者被唤醒后取数据,取完再唤醒生产者生产
对于消费者:如果不可以取数据,就休眠,等待正在生产的生产者唤醒,被唤醒后,取数据,取完后再唤醒生产者,生产者被唤醒后,继续生产
修改后代码如下:
package com.wzy.java8.thread; class Info{ private String title; private String content; private boolean flag = true; //true可以生产数据,不能取走数据 //false可以取走数据,不能生产数据 public synchronized void set(String title,String content) { if(this.flag == false) { //如果不能生产数据,就进行等待,等待其他线程唤醒它 try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //被唤醒后,就进行生产 this.title = title; try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.content = content; this.flag = false;//生产完成,可以取数据了 super.notify();//再唤醒其他线程取数据 } public synchronized void get() { if(this.flag == true) { //如果不能取走数据,就进行等待,等待其他线程唤醒它 try { super.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //被唤醒后,就取走数据,并唤醒生产者 try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.title +" "+ this.content); this.flag = true;//已经取走数据了,可以生产了 super.notify(); } } class Productor implements Runnable{ private Info info = null; public Productor(Info info){ this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { if(i%2 == 0) { this.info.set("偶数", "这是偶数"); }else{ this.info.set("奇数", "这是奇数"); } } } } class Consumers implements Runnable{ private Info info = null; public Consumers(Info info) { this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { this.info.get(); } } } public class Demo2 { /* * sleep() 是Thread的方法,休眠一定时间后会自动唤醒 * wait() 是Object的方法,必须等待其他线程notify(),notifyAll()来唤醒 * */ public static void main(String[] args) { Info info = new Info(); Productor p = new Productor(info); Consumers c = new Consumers(info); new Thread(p).start(); new Thread(c).start(); } }
奇数 这是奇数 偶数 这是偶数 奇数 这是奇数 偶数 这是偶数 奇数 这是奇数 偶数 这是偶数 奇数 这是奇数
相关文章推荐
- OAuth 2.0 协议 授权码授权模式(Authorization Code Grant) -----四种授权模式最常用模式之一
- Delphi 数据类型的说明
- 第六次上机作业
- 新浪微博请求授权显示错误页面的解决方法((error:invalid_request) )
- 最简单实现跨域的方法----使用nginx反向代理
- SpringMVC无法接收日期类型的参数
- C语言(数据类型)
- 快筛菜单
- swift库
- Redis概述
- Python 函数 切片 迭代 列表生成器
- 阿里音乐流行趋势预测大赛一起做-(5)温故知新
- Lombok 安装、入门
- 统计一周系统负荷、内存利用率和磁盘利用率 平均值和峰值
- 谈谈iOS app的线上性能监测
- iOS webView 检测当前网页的请求错误码400、404等错误码
- 博客虚拟主机的购买技巧
- 分治法——二分查找
- POJ 1502 MPI Maelstrom最短路问题
- 有关window.location.hash