【多线程】_线程操作案例——生产者和消费者笔记
来源:互联网 发布:数控铣床加工中心编程 编辑:程序博客网 时间:2024/06/04 19:02
【多线程】_线程操作案例——生产者和消费者笔记
分类: Java
实例要求:在线程操作中有一个经典的案例程序——生产者和消费者问题,生产者不断生产,消费者不断取走生产者生产的产品。
既然是信息,所以就可以定义一个信息的表示类,生产者和消费者都同时占有这个信息类的引用,那么就可以将生产者和消费者两个线程通过信息类联合在一起。
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() ;
- }
- };
0 0
- 【多线程】_线程操作案例——生产者和消费者笔记
- 【多线程】_线程操作案例——生产者和消费者笔记
- 线程操作案例——生产者和消费者
- 多线程案例:生产者和消费者
- 多线程——消费者与生产者案例
- Java多线程操作案例-生产者和消费者实现
- java多线程线程通信——生产者和消费者
- 多线程操作案例---生产者与消费者
- java多线程之生产者和消费者案例
- 线程经典案例---(生产者和消费者)
- Java基础_线程_多线程_生产者消费者问题
- 多线程_生产者消费者
- -java多线程——生产者和消费者
- Android线程—生产者和消费者
- 生产者和消费者多线程--线程间通信
- 生产者和消费者案例
- JavaSE 多线程 线程间通信 生产者与消费者案例
- java自学笔记————多线程 线程间通信之生产者消费者问题;
- VI编辑器
- Notes_20141001
- 字符串的扩展操作22
- Java中字符串在不同字符编码中所占字节数
- 素数筛法
- 【多线程】_线程操作案例——生产者和消费者笔记
- 链表的扩展操作21——legend050709
- 完整 Android SDK 网盘下载
- 【多线程】_线程生命周期笔记
- 【包及访问控制权限】_包的定义及导入笔记
- SCN不一致的情况下如何开库(1)
- 【泛型】_泛型入门笔记
- php 二维数组传递给 js 问题解决记录
- 添加: IE浏览器右键 调用本地客户端