博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
生产者与消费者(综合案例)
阅读量:4346 次
发布时间:2019-06-07

本文共 6906 字,大约阅读时间需要 23 分钟。

基础模型:

  生产者和消费者是一道最为经典的供求案例,而想这供求案例:provider、consumer 在以后进行各种分布式结构开发之后都会被大量采用

  现在假设说目的:生产者负责生产一个完整的数据之后,消费者就要把这些数据取走。于是现在假设生产如下的数据:

    title=老李 note=是个好人

    title=名族败类 note=老方B

范例:编写程序的基础模型

1 package cn.Tony.demo; 2 public  class TestDemo { 3     public static void main(String[] args) throws Exception { 4         Data data=new Data(); 5         new Thread(new DataProvider(data)).start(); 6         new Thread(new DataConsumer(data)).start(); 7     } 8 } 9 class DataProvider implements Runnable{10     private Data data;11     public DataProvider(Data data) {12         this.data=data;13     }14     @Override15     public void run() {16         for(int x=0;x<50;x++) {17             if(x%2==0) {18                 this.data.setTitle("老李");19                 try {20                     Thread.sleep(1000);21                 } catch (InterruptedException e) {22                     e.printStackTrace();23                 }24                 this.data.setNote("是个好人");25             }else {26                 this.data.setTitle("民族败类");27                 try {28                     Thread.sleep(1000);29                 } catch (InterruptedException e) {30                     e.printStackTrace();31                 }32                 this.data.setNote("老方b");33             }34         }35     }36 }37 class DataConsumer implements Runnable{38     private Data data;39     public DataConsumer(Data data) {40         this.data=data;41     }42     @Override43     public void run() {44         for(int x=0;x<50;x++) {45             try {46                 Thread.sleep(1000);47             } catch (InterruptedException e) {48                 // TODO Auto-generated catch block49                 e.printStackTrace();50             }51             System.out.println(this.data.getTitle()+"="+this.data.getNote());52         }53     } 54 }55 class Data{
//负责数据保存56 private String title;57 private String note;58 public void setNote(String note) {59 this.note=note;60 }61 public String getNote() {62 return this.note;63 }64 public void setTitle(String title) {65 this.title=title;66 }67 public String getTitle() {68 return this.title;69 }70 }71

  这个时候就已经可以发现程序出现两类问题:

    数据不完整,明明是好人,结果成败类

    数据的重复操作问题(重复设置,或重复取出)

解决重复问题

  如果要想解决同步问题,那么可以立刻想到使用synchronized关键字来定义同步的操作方法,所以代码修改如下:

1 package cn.Tony.demo; 2 public  class TestDemo { 3     public static void main(String[] args) throws Exception { 4         Data data=new Data(); 5         new Thread(new DataProvider(data)).start(); 6         new Thread(new DataConsumer(data)).start(); 7     } 8 } 9 class DataProvider implements Runnable{10     private Data data;11     public DataProvider(Data data) {12         this.data=data;13     }14     @Override15     public void run() {16         for(int x=0;x<50;x++) {17             if(x%2==0) {18                 this.data.set("老李","老李是个好人");19                 20             }else {21                 this.data.set("民族败类","老放b");22             }23         }24     }25 }26 class DataConsumer implements Runnable{27     private Data data;28     public DataConsumer(Data data) {29         this.data=data;30     }31     @Override32     public void run() {33         for(int x=0;x<50;x++) {34             this.data.get();35         }36     } 37 }38 class Data{
//负责数据保存39 private String title;40 private String note;41 public synchronized void get() {42 try {43 Thread.sleep(50);44 } catch (InterruptedException e) {45 // TODO Auto-generated catch block46 e.printStackTrace();47 }48 System.out.println(this.title+"="+this.note);49 }50 public synchronized void set(String title,String note) {51 this.title=title;52 try {53 Thread.sleep(100);54 } catch (InterruptedException e) {55 // TODO Auto-generated catch block56 e.printStackTrace();57 }58 this.note=note;59 }60 }61

  于是现在发现,整个的程序里面数据的同步问题得到了很好的,但是重复操作的问题更加严重了,

解决数据的重复操作问题:

  如果想要解决重复问题,就要添加唤醒和等待机制,如果想使用这一个功能,那么就要参考Object类中的方法。

  等待 死等:public final void wait()throws InterruptedException

  唤醒第一个等待线程:public final void notify()

  唤醒全部等待线程,那 个优先级高,谁有可能先执行:public final void notifyAll()

范例:通过等待和唤醒机制解决重复操作问题

1 package cn.Tony.demo; 2 public  class TestDemo { 3     public static void main(String[] args) throws Exception { 4         Data data=new Data(); 5         new Thread(new DataProvider(data)).start(); 6         new Thread(new DataConsumer(data)).start(); 7     } 8 } 9 class DataProvider implements Runnable{10     private Data data;11     public DataProvider(Data data) {12         this.data=data;13     }14     @Override15     public void run() {16         for(int x=0;x<50;x++) {17             if(x%2==0) {18                 this.data.set("老李","老李是个好人");19                 20             }else {21                 this.data.set("民族败类","老放b");22             }23         }24     }25 }26 class DataConsumer implements Runnable{27     private Data data;28     public DataConsumer(Data data) {29         this.data=data;30     }31     @Override32     public void run() {33         for(int x=0;x<50;x++) {34             this.data.get();35         }36     } 37 }38 class Data{
//负责数据保存39 private String title;40 private String note;41 //flag=true 表示允许生产不允许消费者取走42 //flag=false 表示生产完毕允许消费者取走不允许生产43 private boolean flag=false;44 public synchronized void get() {45 if(this.flag==false) {
//已经生产了,所以不允许重复生产46 try {47 super.wait();48 } catch (InterruptedException e1) {49 // TODO Auto-generated catch block50 e1.printStackTrace();51 }//等待执行 52 }53 try {54 Thread.sleep(50);55 } catch (InterruptedException e) {56 // TODO Auto-generated catch block57 e.printStackTrace();58 }59 System.out.println(this.title+"="+this.note);60 this.flag=false;//表示生产过了。不允许再生产了61 super.notify();//唤醒等待线程62 }63 public synchronized void set(String title,String note) {64 if(this.flag==true) {
//现在不允许取走65 try {66 super.wait();67 } catch (InterruptedException e) {68 // TODO Auto-generated catch block69 e.printStackTrace();70 }71 }72 this.title=title;73 try {74 Thread.sleep(100);75 } catch (InterruptedException e) {76 // TODO Auto-generated catch block77 e.printStackTrace();78 }79 this.note=note;80 this.flag=true;//继续生产81 super.notify();82 }83 }84

面试题:请解释sleep()与wait()的区别

  sleep()是Thread类的方法到了一定的时间后该休眠自动唤醒

  wait()是Object类中的方法,要想唤醒必须使用notify(),notifyAll()

 

转载于:https://www.cnblogs.com/Tony98/p/10491952.html

你可能感兴趣的文章
python:集合
查看>>
python字符编码与转码
查看>>
python:文件操作
查看>>
python:字典
查看>>
python:函数
查看>>
python:模块
查看>>
python:常用模块
查看>>
python:面向对象
查看>>
python3.5+Django2.2+pymysql+mysql
查看>>
node层设置proxy不生效的原因
查看>>
react 16.3+ 新生命周期 作业
查看>>
KMP整理
查看>>
字典树
查看>>
AC自动机
查看>>
网络赛补题
查看>>
Manacher-马拉车算法
查看>>
字符串哈希+kmp题
查看>>
cookie 和session 的区别
查看>>
AOJ-722 发红包
查看>>
go学习之文件读取问题(需更新)
查看>>