流程:
1:生产者生产商品,如果有商品,不生产,唤醒消费者消费商品;如果没有商品,生产者生产商品,并唤醒消费者消费商品;
2:消费者消费商品,如果有商品,消费商品;如果没有商品,唤醒生产者生产商品,并消费商品;

这里写图片描述

生产者:



public class Producer implements Runnable{
    private Goods  goods;
    private int x = 0;

    public Producer(Goods  goods) {
        this.goods =goods;
    }
    @Override
    public void run() {
        while (true) {
            if (x % 2 == 0) {
                goods.set("蒙牛牛奶", 4);
            } else {
                goods.set("伊利牛奶", 3);
            }
            x++;
        }
    }
}

消费者:


public class Consumer implements Runnable {
    private Goods  goods;

    public Consumer(Goods  goods) {
        this.goods = goods;
    }
    @Override
    public void run() {
        while (true) {
            goods.get();
        }
    }

}

商品:


public class Goods {
    private String name;//商品名称
    private int price;//商品价格
    private boolean flag; // 商品是否存在的标签



    //生产者生产商品  synchronized同步
    //set 方法说明:多线程生产者一直重复调用set方法,由于同步(synchronized),只能完成一次调用一次,
    //第一次没有商品,就生产商品,完成后,有商品,this.notify()唤醒消费者的this.wait()。
    //第二次发现有商品,调动this.wait(),让该方法一直在等待中.直到消费者消费,notify(),唤醒等待,代码继续走下,try-catch后面的代码是生产商品,满足
    //消费者消费完后要生产商品.
    //
    public synchronized void set(String name, int price) {
        // 如果有商品,不生产,等待消费者消费
        if (this.flag) {
            try {

                this.wait();//生产者等待,唤醒消费者消费。消费者消费完商品,唤醒生产者,是从这里醒过来的时候.
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

            // 如果没有商品就生产商品,唤醒消费者消费
            // 设置数据
            this.name = name;
            this.price = price;
            // 修改标记
            this.flag = true;//有商品
            this.notify();//唤醒消费者消费,并同时把方法锁起来,(释放消费者wait的同步锁)


    }
    //消费者消费商品
    // get()方法说明:多线程消费者一直重复调用get方法,由于同步(synchronized),只能完成一次调用一次,
    //第一次是没有商品,该方法走this.wait(),方法在等待,直到生产者this.notify()通知,消费者代码才继续走下去
    //消费商品,this.notify();唤醒生产者this.wait();

    public synchronized void get() {
        //如果没有商品就生产商品,唤醒消费者消费
        if (!this.flag) {
            try {

                this.wait();//消费者等待,并唤醒生产者生产商品,生产者生产完商品,唤醒消费者,唤醒的位置是在这里
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
            // 如果有商品就等待消费者消费
            // 消费商品
            System.out.println(this.name + "---" + this.price);
            // 修改标记
            this.flag = false;//设置已经消费完商品了
            this.notify();  //唤醒生产者生产商品,

    }

}

测试:


public class Test {

    /**
     * @param args
     */
    public static void main(String[] args) {


                //设置商品
                Goods s = new Goods();

                //设置生产者
                Producer producer = new Producer(s);
                //设置消费者
                Consumer consumer = new Consumer(s);

                //线程类
                Thread prodTh = new Thread(producer,"生产者");
                Thread conTh = new Thread(consumer,"消费者");

                //启动线程
                conTh.start();
                prodTh.start();
    }

}
posted on 2017-04-07 01:13  2637282556  阅读(158)  评论(0编辑  收藏  举报