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

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

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();
        
    }
}

 

奇数  这是奇数
偶数  这是偶数
奇数  这是奇数
偶数  这是偶数
奇数  这是奇数
偶数  这是偶数
奇数  这是奇数

 

posted on 2016-05-27 11:18  wzyy  阅读(295)  评论(0编辑  收藏  举报