【多线程】_线程操作案例——生产者和消费者笔记
来源:互联网 发布:深圳市软件产业基地4栋 编辑:程序博客网 时间:2024/06/05 08:49
实例要求:在线程操作中有一个经典的案例程序——生产者和消费者问题,生产者不断生产,消费者不断取走生产者生产的产品。
既然是信息,所以就可以定义一个信息的表示类,生产者和消费者都同时占有这个信息类的引用,那么就可以将生产者和消费者两个线程通过信息类联合在一起。
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
mldn-->JAVA讲师
mldn-->JAVA讲师
李兴华-->www.mldnjava.cn
以上的代码将之前的两个问题全部暴露出来了。
之所以会出现内容不对应的情况,是因为中间加入了延迟操作,所以有可能产生不同步的问题,那么此时,可以使用同步解决设置内容的问题。
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
mldn-->www.mldnjava.cn
mldn-->www.mldnjava.cn
以上的代码解决了数据完整性问题,但是依然存在了重复取的问题,既然有重复取,则肯定有重复设置问题。
并没有达到,设置一个取走一个的功能要求。
如果要想采用以上的一种机制,则必须依靠Object 类中的方法支持。
Object类对线程的支持——等待与唤醒
Object 类是所有类的父类,在此类中有以下几个方法是对线程操作有所支持的。
唤醒现有两个方法:notify,notifyAll
notify()方法唤醒第一个等待的线程执行
notifyAll()方法唤醒所有的等待线程执行
既然是信息,所以就可以定义一个信息的表示类,生产者和消费者都同时占有这个信息类的引用,那么就可以将生产者和消费者两个线程通过信息类联合在一起。
class Info{//定义信息类 private String name = "牛儿吃草"; private String content = "Java 讲师"; 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{ private Info info = null; public Producer(Info info){ this.info = info; } public void run(){ boolean flag = false; for(int i=0;i<50;i++){ if(flag){ this.info.setName("李兴华"); try{ Thread.sleep(90); }catch(InterruptedException e){ e.printStackTrace(); } this.info.setContent("JAVA讲师"); flag = false; }else{ this.info.setName("mldn"); try{ Thread.sleep(90); }catch(InterruptedException e){ e.printStackTrace(); } this.info.setContent("www.mldnjava.cn");//设置内容 flag = true; } } }}//生产者生产50次信息,中间为了更好的发现问题,加入了延迟操作。//实现消费者,消费者要不断的取出。class Consumer implements Runnable{ private Info info = null; public Consumer(Info info){ this.info = info; } public void run(){ for(int i=0;i<50;i++){ try{ Thread.sleep(90); }catch(InterruptedException e){ e.printStackTrack(); } System.out.println(this.info.getName()+ "-->"+this.info.getContent() ); } }}//通过测试代码来发现程序的问题:public class ThreadCaseDemo01{ public static void main(String args[]){ Info info = new Info(); Producer pro = new Producer(info); //生产者 Consumer con = new Consumer(info); new Thread(pro).start(); new Thread(con).start(); }}
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
mldn-->JAVA讲师
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
李兴华-->www.mldnjava.cn
mldn-->JAVA讲师
mldn-->JAVA讲师
李兴华-->www.mldnjava.cn
以上的代码将之前的两个问题全部暴露出来了。
之所以会出现内容不对应的情况,是因为中间加入了延迟操作,所以有可能产生不同步的问题,那么此时,可以使用同步解决设置内容的问题。
class Info{//定义信息类 private String name = "牛儿吃草"; private String content = "Java 讲师"; public synchronized void set(String name,String content){ this.setName(name); //设置名称 try{ Thread.sleep(300); }catch(InterruptedException e){ e.printStackTrace(); } this.setContent(content); } public synchronized void get(){ try{ Thread.sleep(300); }catch(InterruptedException e){ e.printStackTrace(); } System.out.println(this.getName()+"-->"+this.getContent()); } 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{ private Info info = null; public Producer(Info info){ this.info = info; } public void run(){ boolean flag = false; for(int i=0;i<50;i++){ if(flag){ this.info.set("李兴华","JAVA讲师"); flag = false; }else{ this.info.set("mldn","www.mldnjava.cn"); 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<50;i++){ this.info.get(); } }}public class ThreadCaseDemo02{ public static void main(String args[]){ Info info = new Info(); Producer pro = new Producer(info); Consumer con = new Consumer(info); new Thread(pro).start(); new Thread(con).start(); }}
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
牛儿吃草-->JAVA讲师
mldn-->www.mldnjava.cn
mldn-->www.mldnjava.cn
以上的代码解决了数据完整性问题,但是依然存在了重复取的问题,既然有重复取,则肯定有重复设置问题。
并没有达到,设置一个取走一个的功能要求。
如果要想采用以上的一种机制,则必须依靠Object 类中的方法支持。
Object类对线程的支持——等待与唤醒
Object 类是所有类的父类,在此类中有以下几个方法是对线程操作有所支持的。
唤醒现有两个方法:notify,notifyAll
notify()方法唤醒第一个等待的线程执行
notifyAll()方法唤醒所有的等待线程执行
class Info{ // 定义信息类 private String name = "李兴华"; // 定义name属性 private String content = "JAVA讲师" ; // 定义content属性 private boolean flag = false ; // 设置标志位 public synchronized void set(String name,String content){ if(!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(){ if(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 = false ; // 定义标记位 for(int i=0;i<50;i++){ if(flag){ this.info.set("李兴华","JAVA讲师") ; // 设置名称 flag = false ; }else{ this.info.set("mldn","www.mldnjava.cn") ; // 设置名称 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<50;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() ; new Thread(con).start() ; }};
- 【多线程】_线程操作案例——生产者和消费者笔记
- 【多线程】_线程操作案例——生产者和消费者笔记
- 线程操作案例——生产者和消费者
- 多线程案例:生产者和消费者
- 多线程——消费者与生产者案例
- Java多线程操作案例-生产者和消费者实现
- java多线程线程通信——生产者和消费者
- 多线程操作案例---生产者与消费者
- java多线程之生产者和消费者案例
- 线程经典案例---(生产者和消费者)
- Java基础_线程_多线程_生产者消费者问题
- 多线程_生产者消费者
- -java多线程——生产者和消费者
- Android线程—生产者和消费者
- 生产者和消费者多线程--线程间通信
- 生产者和消费者案例
- JavaSE 多线程 线程间通信 生产者与消费者案例
- java自学笔记————多线程 线程间通信之生产者消费者问题;
- java反射机制访问对象的私有变量
- jQuery获取,设置下拉框的值
- String 与 StingBuffer的区别
- FFMEG开发教程--(02)ffmpeg输出到屏幕
- busybox简介和使用
- 【多线程】_线程操作案例——生产者和消费者笔记
- 固定表头
- android之文件读写实例测试
- Repeater隔行换色、鼠标停留在上面是变色
- 关于hadoop的API写文件的备份数问题
- 通过Android系统日志监听程序启动事件
- 网络流 1024
- 立体视觉算法-SGBM(一)
- 【多线程】_线程生命周期笔记