• 多线程模拟生产者和消费者模型


    模拟生产者一边生产数据,消费者一边取出数据,
    但以下代码会出现数据错位现象和重复生产,不符合我们的要求

    package com.wzy.java8.thread;
    class Info{ private String title; private String content; public void setContent(String content) { this.content = content; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public String getTitle() { return title; } } class Productor implements Runnable{ private Info info = null; public Productor(Info info){ this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { if(i%2 == 0) { this.info.setTitle("偶数"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是偶数"); }else{ this.info.setTitle("奇数"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } this.info.setContent("这是奇数"); } } } } class Consumers implements Runnable{ private Info info = null; public Consumers(Info info) { this.info = info; } @Override public void run() { for(int i=0;i<100;i++) { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(info.getTitle()+" "+info.getContent()); } } } public class Demo2 { public static void main(String[] args) { Info info = new Info(); Productor p = new Productor(info); Consumers c = new Consumers(info); new Thread(p).start(); new Thread(c).start(); } }
    奇数  这是偶数
    偶数  这是奇数
    奇数  这是偶数
    偶数  这是奇数
    奇数  这是偶数

    使用同步synchronized可以解决数据错位问题

    使用super.wait(),super.notify();可以解决重复生产问题

    思路:对于生产者:如果不可以生产,就休眠,等待正在取数据的消费者唤醒,被唤醒后,再生产,生产完成后唤醒消费者;消费者被唤醒后取数据,取完再唤醒生产者生产

    对于消费者:如果不可以取数据,就休眠,等待正在生产的生产者唤醒,被唤醒后,取数据,取完后再唤醒生产者,生产者被唤醒后,继续生产

    修改后代码如下:

    package com.wzy.java8.thread;
    
    class Info{
        private String title;
        private String content;
        private boolean flag = true;
        //true可以生产数据,不能取走数据
        //false可以取走数据,不能生产数据
        
        public synchronized void set(String title,String content) {
            if(this.flag == false) {
                //如果不能生产数据,就进行等待,等待其他线程唤醒它
                try {
                    super.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //被唤醒后,就进行生产
            this.title = title;
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            this.content = content;
            this.flag = false;//生产完成,可以取数据了
            super.notify();//再唤醒其他线程取数据
        }
        public synchronized void get() {
            if(this.flag == true) {
                //如果不能取走数据,就进行等待,等待其他线程唤醒它
                try {
                    super.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //被唤醒后,就取走数据,并唤醒生产者
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(this.title +"  "+ this.content);
            this.flag = true;//已经取走数据了,可以生产了
            super.notify();
            
        }
        
    }
    class Productor implements Runnable{
        private Info info = null;
        public Productor(Info info){
            this.info = info;
        }
        @Override
        public void run() {
            for(int i=0;i<100;i++) {
                if(i%2 == 0) {
                    this.info.set("偶数", "这是偶数");
                }else{
                    this.info.set("奇数", "这是奇数");
                }
            }
        }
        
        
    }
    class Consumers implements Runnable{
        private Info info = null;
        public Consumers(Info info) {
            this.info = info;
        }
        @Override
        public void run() {
            for(int i=0;i<100;i++) {
                
                this.info.get();
            }
        }
        
    }
    public class Demo2 {
        /*
         * sleep() 是Thread的方法,休眠一定时间后会自动唤醒
         * wait() 是Object的方法,必须等待其他线程notify(),notifyAll()来唤醒
         * */
        
        public static void main(String[] args) {
            Info info = new Info();
            Productor p = new Productor(info);
            Consumers c = new Consumers(info);
            new Thread(p).start();
            new Thread(c).start();
            
        }
    }
    奇数  这是奇数
    偶数  这是偶数
    奇数  这是奇数
    偶数  这是偶数
    奇数  这是奇数
    偶数  这是偶数
    奇数  这是奇数
  • 相关阅读:
    “Win10 UAP 开发系列”之 在MVVM模式中控制ListView滚动位置
    “Win10 UAP 开发系列”之主题模式切换
    Windows Phone 8.1中AppBarToggleButton的绑定问题
    Windows Phone 8.1中处理后退键的HardwareButtons.BackPressed事件
    在后台代码中动态生成pivot项并设置EventTrigger和Action的绑定
    数据对象转json与md5加密注意事项
    iOS中wkwebview加载本地html的要点
    iOS项目开发常用功能静态库
    AFN中请求序列化的设置
    swift中的AnyHashable
  • 原文地址:https://www.cnblogs.com/wwzyy/p/5533961.html
Copyright © 2020-2023  润新知