java挑战高并发 之(11):生产者—消费者模型(含代码)
来源:互联网 发布:360优化 大师官网下载 编辑:程序博客网 时间:2024/04/26 05:54
生产者消费者问题是线程模型中的经典问题:生产者和消费者在同一时间段内共用同一存储空间,生产者向空间里生产数据,而消费者取走数据。
这里实现如下情况的生产--消费模型:
生产者不断交替地生产两组数据“姓名--1 --> 内容--1”,“姓名--2--> 内容--2”,消费者不断交替地取得这两组数据,这里的“姓名--1”和“姓名--2”模拟为数据的名称,“内容--1 ”和“内容--2 ”模拟为数据的内容。
由于本程序中牵扯到线程运行的不确定性,因此可能会出现以下问题:
1、假设生产者线程刚向数据存储空间添加了数据的名称,还没有加入该信息的内容,程序就切换到了消费者线程,消费者线程将把信息的名称和上一个信息的内容联系在一起;
2、生产者生产了若干次数据,消费者才开始取数据,或者是,消费者取完一次数据后,还没等生产者放入新的数据,又重复取出了已取过的数据。
问题1很明显要靠同步来解决,问题2则需要线程间通信,生产者线程放入数据后,通知消费者线程取出数据,消费者线程取出数据后,通知生产者线程生产数据,这里用wait/notify机制来实现。
详细的实现代码如下:
class Info{// 定义信息类private String name = "name";//定义name属性,为了与下面set的name属性区别开private String content = "content" ;// 定义content属性,为了与下面set的content属性区别开private boolean flag = true ;// 设置标志位,初始时先生产public synchronized void set(String name,String content){while(!flag){try{super.wait() ;}catch(InterruptedException e){e.printStackTrace() ;}}this.setName(name) ;// 设置名称try{Thread.sleep(300) ;}catch(InterruptedException e){e.printStackTrace() ;}this.setContent(content) ;// 设置内容flag = false ;// 改变标志位,表示可以取走super.notify();}public synchronized void get(){while(flag){try{super.wait() ;}catch(InterruptedException e){e.printStackTrace() ;}}try{Thread.sleep(300) ;}catch(InterruptedException e){e.printStackTrace() ;}System.out.println(this.getName() + " --> " + this.getContent()) ;flag = true ;// 改变标志位,表示可以生产super.notify();}public void setName(String name){this.name = name ;}public void setContent(String content){this.content = content ;}public String getName(){return this.name ;}public String getContent(){return this.content ;}}class Producer implements Runnable{// 通过Runnable实现多线程private Info info = null ;// 保存Info引用public Producer(Info info){this.info = info ;}public void run(){boolean flag = true ;// 定义标记位for(int i=0;i<10;i++){if(flag){this.info.set("姓名--1","内容--1") ;// 设置名称flag = false ;}else{this.info.set("姓名--2","内容--2") ;// 设置名称flag = true ;}}}}class Consumer implements Runnable{private Info info = null ;public Consumer(Info info){this.info = info ;}public void run(){for(int i=0;i<10;i++){this.info.get() ;}}}public class ThreadCaseDemo03{public static void main(String args[]){Info info = new Info();// 实例化Info对象Producer pro = new Producer(info) ;// 生产者Consumer con = new Consumer(info) ;// 消费者new Thread(pro).start() ;//启动了生产者线程后,再启动消费者线程try{Thread.sleep(500) ;}catch(InterruptedException e){e.printStackTrace() ;}new Thread(con).start() ;}}
另外,在run方法中,二者循环的次数要相同,否则,当一方的循环结束时,另一方的循环依然继续,它会阻塞在wait()方法处,而等不到对方的notify通知。
0 0
- java挑战高并发 之(11):生产者—消费者模型(含代码)
- 【Java并发编程】:生产者—消费者模型(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)
- Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)
- 【Java并发编程】之十三:生产者—消费者模型(含代码)(r)
- Java并发编程】之十三:生产者—消费者模型(含代码)
- Java并发编程之十六:生产者—消费者模型(含代码)
- 第十三篇:生产者—消费者模型(含代码)
- java并发编程(十六)--生产者—消费者模型
- java并发之生产者消费者模型
- java挑战高并发(6):Runnable和Thread实现多线程的区别(含代码)
- 生产者-消费者模型(Java)
- java线程深度解析(五)——并发模型(生产者-消费者)
- java线程深度解析(五)——并发模型(生产者-消费者)
- Java线程同步:生产者-消费者 模型(代码示例)
- Java挑战高并发(3) 线程挂起、恢复与终止的正确方法(含代码)
- Android学习笔记(一):AIDL
- Android盒子功能测试
- redis之lpush、rpush、lset、lrem
- oracle的查询数据表(一)
- Java中如何使用转义转义字符?
- java挑战高并发 之(11):生产者—消费者模型(含代码)
- union和union all的区别
- 关于java报空指针错误的几种常见情况
- hexo next 主题打开博客过慢的解决办法
- Android开发之Service与多个Activity通信
- javaScript总结20160809
- mysql 5.6无法启动问题一例
- 初学React
- mysql 5.6.24升级mysql 5.7.14的实验