面对多线程学习生产者与消费者是最基本的实例

对于java后端开发的人员必须要掌握,还有考研考试计算机操作系统的同鞋。

下面是三个实例对于生产者与消费者的的例子,层层递进,逐步解决问题。

问题:生产者——设置信息名字name,和内容content

消费者——负责取出设置的信息。

一、基本实现

由于线程的不确定性可能出现以下问题:

(1)消费者取出的信息不匹配,即不是由同一个生产者设置的信息

(2)生产者生产了多个信息,消费者才开始取出信息,或消费者取出的重复的信息。

上面的问题下面会逐一解决,下面先看出现问题的程序:

packageli.xin.hua.ch9;/*线程生产者与向消费者最基本实现,问题有:

* 1、数据不匹配

* 2、数据重复取出已经取过的数据*/

classInfo{privateString name;privateString content;publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicString getContent() {returncontent;

}public voidsetContent(String content) {this.content =content;

}

};class Producer implementsRunnable{private Info info=null;publicProducer(Info info){this.info=info;

}public voidrun(){boolean flag=false;for(int i=0;i<10;++i)

{if(flag){this.info.setName("胡歌");try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.info.setContent("林殊");

flag=false;

}else{this.info.setName("刘涛");try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.info.setContent("郡主");

flag=true;

}

}

}

};class Consumer implementsRunnable{private Info info=null;publicConsumer(Info info){this.info=info;

}public voidrun(){for(int i=0;i<10;i++)

{try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(this.info.getName()+"---饰演--->"+this.info.getContent());

}

}

};public classProducer_Comsumer01 {public static voidmain(String[] args) {

Info info=newInfo();

Producer pro=newProducer(info);

Consumer con=newConsumer(info);newThread(pro).start();newThread(con).start();

}

}

运行结果如下图:

发现胡歌不仅饰演林殊,还饰演郡主,哈哈哈哈哈哈!

问题是线程生产的信息取出时是不匹配的,解决方法使用同步机制——synchronized

二、加入同步机制

将设置名称与内容定义在一个同步方法中,代码如下:

packageli.xin.hua.ch9;/*线程生产者与向消费者最基本实现

* 1、数据不匹配通过同步机制已经解决

* 2、重复取数据问题还是有*/

classInfo02{privateString name;privateString content;public synchronized voidget() {try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(this.name+"---饰演--->"+this.content);

}public synchronized voidset(String name,String content) {this.name=name;try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.content =content;

}

};class Producer02 implementsRunnable{private Info02 info=null;publicProducer02(Info02 info){this.info=info;

}public voidrun(){boolean flag=false;for(int i=0;i<10;++i)

{if(flag){this.info.set("胡歌","林殊");

flag=false;

}else{this.info.set("刘涛","郡主");

flag=true;

}

}

}

};class Consumer02 implementsRunnable{private Info02 info=null;publicConsumer02(Info02 info){this.info=info;

}public voidrun(){for(int i=0;i<10;i++)

{try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.info.get();

}

}

};public classProducer_Comsumer02 {public static voidmain(String[] args) {

Info02 info=newInfo02();

Producer02 pro=newProducer02(info);

Consumer02 con=newConsumer02(info);newThread(pro).start();newThread(con).start();

}

}

运行结果如下图:

胡歌与刘涛饰演的角色没有匹配错误,但信息反复取出,需要Object类中的方法来解决。

三、加入等待唤醒机制

Object类中wait()、notify()方法,扩充点知识:wai()方法会释放线程的对象的锁,而sleep()方法不会。

设置一个标志位flag,

当flag为true时:

可以进行生产,但不能取出数据,若此时消费者线程恰巧抢到CPU资源,想要执行消费者程序,

必须将消费者线程等待wait()。生产者生产完成后要修改标示位(表示可以消费者可以取出信息了),和唤醒notify()被等待的线程。

当flag为false时:

消费者可以取出信息,但生产者不能生产信息,若此时生产者线程恰巧抢到CPU资源,想要执行生产者程序,

必须将生产者线程等待wait()。消费者完成取出信息后要修改标示位(表示可以生产者可以生产信息了),和唤醒notify()被等待的线程。

packageli.xin.hua.ch9;/*线程生产者与向消费者最基本实现

* 1、数据不匹配通过同步机制已经解决

* 2、重复取数据问题通过等待唤醒机制已经解决

* 当flag为true时允许生产者生产,若此时消费者进入则要等待

* 当flag为false时允许消费者取出信息,若此时生产者进入则要等待*/

classInfo03{privateString name;privateString content;private boolean flag=true; /*设置标示位:true是生产的时间,false是消费的时间。

第一次先生产*/

public synchronized voidset(String name,String content) {if(!flag) /*现在不是生产的时间,线程要等待,唤醒后才能生产。*/{try{super.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}this.name=name;try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.content =content;

flag=false;super.notify();

}public synchronized voidget() {if(flag) /*消费者*/{try{super.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}

System.out.println(this.name+"---饰演--->"+this.content);

flag=true;super.notify();

}

};class Producer03 implementsRunnable{private Info03 info=null;publicProducer03(Info03 info){this.info=info;

}public voidrun(){boolean flag=false;for(int i=0;i<10;++i)

{if(flag){this.info.set("胡歌","林殊");

flag=false;

}else{this.info.set("刘涛","郡主");

flag=true;

}

}

}

};class Consumer03 implementsRunnable{private Info03 info=null;publicConsumer03(Info03 info){this.info=info;

}public voidrun(){for(int i=0;i<10;i++)

{try{

Thread.sleep(50);

}catch(InterruptedException e) {

e.printStackTrace();

}this.info.get();

}

}

};public classProducer_Comsumer03 {public static voidmain(String[] args) {

Info03 info=newInfo03();

Producer03 pro=newProducer03(info);

Consumer03 con=newConsumer03(info);newThread(pro).start();newThread(con).start();

}

}

运行结果如下图:

胡歌与刘涛交替出现,并且角色匹配正确。

java多线程生产者与消费者案例_多线程操作实例——生产者与消费者相关推荐

  1. java并行流 阻塞主线程_多线程入门案例与java8的并行流

    java8 实例请移步https://www.cnblogs.com/ngLee/p/14021859.html 进程与线程 进程是所有线程的集合,每一个线程是进程中的一条执行路径. 多线程的创建方式 ...

  2. java点击按钮结线程_多线程的Java应用程序在调试工具Netbeans中单击“停止”按钮时输出一个奇怪的结果...

    我使用wait()和notify()机制学习了java中的多线程. 但我很好奇输出一个简单的多线程Java应用程序. 代码如下: class Q { int n; boolean valueSet = ...

  3. java线程同步机制有哪些_多线程同步机制包括哪些,java线程同步机制

    多线程同步机制包括哪些什么是多线程同步机制,多线程同步机制包括:1.临界段用于实现"独占占有":2.信号量用于跟踪有限的资源:3.互斥是核心对象,可以实现不同线程之间的" ...

  4. java线程同步机制有哪些_多线程同步机制包括哪些

    多线程同步机制包括:1.Critical Section用来实现"排他性占有":2.Semaphore被用来追踪有限的资源:3.Mutex是核心对象,可以在不同的线程之间实现&qu ...

  5. java实现线性表的案例_数据结构—线性表(LinearList)的原理以及Java实现案例

    线性表:零个或多个数据元素的有限序列.包括数组.链表.栈空间.队列等结构都属于线性表. 本文将介绍Java线性表中的数组.链表的实现逻辑,并附有数组线性表.单链表.静态链表的Java实现源码. 数据结 ...

  6. java城市公交查询系统案例_基于JAVA的城市公共交通查询系统的设计与实现

    科技与信息 2018.12 计算机产品与流通 159 基于 JAVA 的城市公共交通查询系统的设计与实现 □ 苏楠 摘要:公共交通查询系统是城市交通的组成部分之一,也是一个城市实现现代化发展的必然产物 ...

  7. java 边读边写文件_文件操作--边读边写,在指定位置添加内容(避免乱码)

    [java]代码库/** * @param lineNumber 选择要添加内容的行数 * @param attribute1 选择要添加的内容1 * @param attribute2 选择要添加的 ...

  8. jQuery基本使用_选择器_淘宝服饰切换案例_样式操作_效果_王者荣耀手风琴

    文章目录 一.基本使用 1.jquery入口函数 2.$符 3.DOM对象和jQuery对象的转换 二.jquery选择器 1.基础选择器 2.隐式迭代 3.筛选选择器 4.筛选方法 5.排他思想 淘 ...

  9. java将图片上传数据库_〔技巧实例〕轻松实现将上传图片到数据库

    很久就想自己写一写程序了,不过由于赖就不想写我,今天刚好有空,所以写了这个小小的程序很容易一看就知道的,不多说了就此开始: 我们做一个上传的.数据据库的字段就id自动编号 big 字段类型是 OLE ...

最新文章

  1. php html 变量,PHP与HTML混编,使用PHP变量代替数据--20190221
  2. 电大计算机要学多久,电大计算机应用基础是我们必须要学习的科目吗
  3. (char*)x C语言中的和*的详解
  4. 中国电网招聘 计算机岗位
  5. MyCat分布式数据库集群架构工作笔记0013---高可用_Mycat双主双从复制配置上
  6. 通过XMPP协议实现推送信息
  7. 常用牛人主页链接(计算机视觉、模式识别、机器学习相关方向,陆续更新。。。。)...
  8. 格式化U盘的工具(USB无法识别 ,无法格式化 )
  9. 百度Java出现:“现在学java的都是傻子”相关搜索!
  10. win7电脑变身WiFi热点,让手机、笔记本共享上网
  11. AM335x硬件开发使用指南(一)
  12. 计算机科学与探索期刊审稿周期,计算机科学与探索期刊 从投稿到录用过程
  13. 电力系统随机潮流概率潮流计算MATLAB程序包含蒙特卡洛模拟法、半不变量法+级数展开
  14. 针对电子企业的仓储需求,提出WMS仓储管理系统解决方案
  15. 2022-2028年中国异戊二烯行业市场运营格局及前景战略分析报告
  16. 第4章 介绍Python对象类型
  17. 「镁客·请讲」慧川智能康洪文:打造一个“AI+视频云平台”的中央厨房
  18. Vue编译时写在style中的路径问题
  19. 人际交往中,如何拒绝别人的要求
  20. 半导体产业,城市,发展讨论

热门文章

  1. Codeforces 510 E. Fox And Dinner
  2. 我学习的第一个uiautomator从创建到运行结束
  3. 页面间参数传递---基于Vue的uniapp手机端_前端UI_uview工作笔记005
  4. ES6-ES11新特性_ECMAScript相关名词介绍_---JavaScript_ECMAScript工作笔记002
  5. Unity3D引擎工作笔记0001---认识Unity3D 5游戏开发引擎
  6. FastDfs工作笔记002---SpringBoot集成FastDfs
  7. RabbitMq学习笔记004---在CentOS7上安装RabbitMQ
  8. java在线支付---01_在线支付功能的演示与概述
  9. android学习笔记---59_各种图形的使用介绍,android炫酷效果的实现
  10. Android学习笔记---24_网络通信之网页源码查看器