多线程等待唤醒案例

前提:一个线程生产,一个线程消费,不能连续生产,不能连续消费 。线程间等待唤醒机制(生产者,消费者)(线程之间的通信)。

案例:生产者生产产品,消费者消费产品。不能连续生产,不能连续消费 。

分析问题:

1、生产者生产产品:定义count++,消费者消费产品:输出count;

2、设置flag,如果为true则有产品,需要消费者消费,生产者等待;如果为false则没有产品,需要消费者等待。

3、加锁来控制线程间的切换,防止在生产和消费时发生线程切换。

4、利用wait和notify方法来保证生产一个消费一个,防止连续生产与消费。

实现:

产品类:

public class Goods {
    //代表产品的count
    private int count;
    //代表是否有产品的flag
    private boolean flag;

    public Goods() {
    }

    public Goods (int count, boolean flag) {
        this.count = count;
        this.flag = flag;
    }

    /*
       getCount 改造成消费产品方法
       直接输出count
     */
    public void getCount() {
        System.out.println("消费了第"+count+"个产品");
    }

    /*
       setCount 改造成生产产品
       count++
     */
    public void setCount() {
        count++;
        System.out.println("生产了第"+count+"个产品");
    }

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

生产者:

public class Product implements Runnable{
//这里的有参构造是为了防止加锁时产生锁对象不一致的问题,导致失败   
 private Goods goods;

    public Product(Goods goods) {
        this.goods= goods;
    }

    @Override
    public void run() {
        while(true){

            try {
                Thread.sleep(100L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            synchronized (goods){
                //1.判断flag是否为true,如果是true,证明有产品,生产线程等待
                if (goods.isFlag()==true){
                    try {
                        goods.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

                //2.如果flag为false,证明没有产品,开始生产
                goods.setCount();
                //3.改变flag状态,为true,证明生产完了,有包子产品
                //4.唤醒消费线程
                goods.notify();
            }
        }
    }
}

消费者

public class Consumer implements Runnable{
    private Goods goods;

    public Consumer(Goods  goods) {
        this.goods= goods;
    }

    @Override
    public void run() {
        while(true){

            try {
                Thread.sleep(100L);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            synchronized (goods){
                //1.判断flag是否为false,如果是false,证明没有产品,消费线程等待
                if (goods.isFlag()==false){
                    try {
                        goods.wait();
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                }

                //2.如果flag为true,证明有产品,开始消费
                goods.getCount();
                //3.改变flag状态,为false,证明消费完了,没有产品了
                goods.setFlag(false);
                //4.唤醒生产线程
                goods.notify();
            }
        }
    }
}

test类:

public class Test01 {
    public static void main(String[] args) {
        Goods goods= new Goods ();
//定义一个共有的产品类对象,提供给生产者与消费者产生同一个锁对象。
        Product product = new Product(goods);
        Consumer consumer = new Consumer(goods);

        Thread t1 = new Thread(product);
        Thread t2 = new Thread(consumer);

        t1.start();
        t2.start();
    }
}


 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值