多线程经典模型-生产者消费

需求:生产者生产一个,消费者消费一个

问题引出


class Info{
    private String name;
    private String desc;
    public  Info(){

    }
    public  Info(String name,String desc){
        this.name = name;
        this.desc = desc;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDesc() {
        return desc;
    }

    public void setDesc(String desc) {
        this.desc = desc;
    }

    @Override
    public String toString() {
        return "Info{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}
class Product implements Runnable{
    private Info info;
    public Product(Info info){
        this.info = info;

    }
    @Override
    public void run() {

        for(int i = 0;i<100;i++){
            if(i % 2 == 0){
                this.info.setName("小郑");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.setDesc("钢笔");
            }else{
                this.info.setName("小李");
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                this.info.setDesc("笔记本");
            }
            System.err.println(info.getName()+" 生产->"+info.getDesc());
        }
    }
}

class Consume implements Runnable{
    private Info info;
    public Consume(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.err.println(info.getName()+"消费->"+info.getDesc());
        }
    }
}
public class ProductCustumer {

    public static void main(String args[]){
        Info info = new Info();
        new Thread(new Product(info)).start();
        new Thread(new Consume(info)).start();
    }
}


结果:
小郑消费->null
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->钢笔
小郑 生产->钢笔
小李消费->笔记本
小李 生产->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑消费->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李消费->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小郑消费->钢笔
小李 生产->笔记本
小李消费->笔记本
小郑 生产->钢笔
小李消费->钢笔
小李消费->笔记本
小李 生产->笔记本

Process finished with exit code 0
有上面结果可以看出产生了两个问题1.生产人和产物不对应,2.违背生产一个消费一个规则

解决 生产人和产物不对应问题

生产人和产物不对应是线程不同步导致,修改代码如下

class Info{
    private String name;
    private String desc;
    public synchronized void set(String name,String desc){
        this.name = name;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.desc = desc;
        System.err.println(name+" 生产->"+desc);
    }

    public synchronized void get(){
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.err.println(name+" 消费->"+desc);
    }
}

class Product implements Runnable{
    private Info info;
    public Product(Info info){
        this.info = info;
    }
    @Override
    public void run() {
        for(int i = 0;i<100;i++){
            if(i % 2 == 0){
                info.set("小郑","钢笔");
            }else{
                info.set("小李","笔记本");
            }
        }
    }
}

class Consume implements Runnable{
    private Info info;
    public Consume(Info info){
        this.info = info;

    }
    @Override
    public void run() {
        for(int i = 0; i< 100;i++){
            info.get();
        }
    }
}

public class ProductCustumer {

    public static void main(String args[]){
        Info info = new Info();
        new Thread(new Product(info)).start();
        new Thread(new Consume(info)).start();
    }
}

结果:
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小郑 生产->钢笔
小李 生产->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本
小李 消费->笔记本

解决 违背生产一个消费一个规则


package a002;

/**
 * Created by Administrator on 2018/2/23 0023.
 */

class Info{
    // falg true 可以生产,但是不能消费  false 可以消费,但不可以生产
    private Boolean falg  = true;  //默认为true 先生产
    private String name;
    private String desc;
    public synchronized void set(String name,String desc){
        if(falg == false){  //等待消费
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.name = name;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        this.desc = desc;
        System.err.println(name+" 生产->"+desc);
        //生产完成修改开关
        this.falg = false;
        //唤醒生产线程
        notify();
    }

    public synchronized void get(){
        if(falg){ //等待生产
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.err.println(name+" 消费->"+desc);
        falg = true;
        notify();
    }
}

class Product implements Runnable{
    private Info info;
    public Product(Info info){
        this.info = info;
    }
    @Override
    public void run() {
        for(int i = 0;i<100;i++){
            if(i % 2 == 0){
                info.set("小郑","钢笔");
            }else{
                info.set("小李","笔记本");
            }
        }
    }
}

class Consume implements Runnable{
    private Info info;
    public Consume(Info info){
        this.info = info;

    }
    @Override
    public void run() {
        for(int i = 0; i< 100;i++){
            info.get();
        }
    }
}
public class ProductCustumer {
    public static void main(String args[]){
        Info info = new Info();
        new Thread(new Product(info)).start();
        new Thread(new Consume(info)).start();
    }
}


结果:
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
小郑 生产->钢笔
小郑 消费->钢笔
小李 生产->笔记本
小李 消费->笔记本
posted @ 2018-02-23 09:58  xiaofei001  阅读(130)  评论(0)    收藏  举报