多多线程案例之wait和notifyAll

  • 模拟面包店生产消费流程:
  • 10个生产者,每个每次生产3个;
  • 20个消费者,每个每次消费1个 ;
  • 最大库存100
public class BreadShop {

    /**
     * 面包店库存
     */
    private static int COUNT;
    /**
     * 生产者
     */
    public static class Producer implements Runnable{
        private String name;

        public Producer(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            //一直生产

            try {
                while(true){
                    synchronized (BreadShop.class) {
                        if (COUNT + 3 > 100) {
                            //库存已满,进入等待
                            BreadShop.class.wait();
                        }else{
                            COUNT += 3;
                            System.out.printf("生产者%s生产了3个面包,库存%s\n", name, COUNT);
                            //此时可以生产了,就通知阻塞线程进入就绪态
                            BreadShop.class.notifyAll();
                            //模拟耗时
                            Thread.sleep(200);
                        }
                    }
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 消费者
     */
    public static class Consumer implements Runnable{
        private String name;

        public Consumer(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                while (true){
                    synchronized (BreadShop.class){
                            if (COUNT==0){
                                //库存已空,无法消费
                                BreadShop.class.wait();
                            }else{
                                //库存未空可以消费
                                COUNT--;
                                System.out.printf("消费者%s消费了1个面包,库存%s\n",name,COUNT);
                                //通知阻塞线程计入就绪态可以消费了
                                BreadShop.class.notifyAll();
                                //模拟耗时
                                Thread.sleep(200);
                            }
                    }
                    //模拟耗时
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //同时启动20个消费者
        Thread[] consumers=new Thread[20];
        for (int i=0;i<20;i++){
            consumers[i]=new Thread(new Consumer(String.valueOf(i)));
        }
        //同时启动10个生产者
        Thread[] producers=new Thread[10];
        for (int i=0;i<10;i++){
            producers[i]=new Thread(new Producer(String.valueOf(i)));
        }

        for(Thread t:consumers){
            t.start();
        }
        for (Thread t:producers){
            t.start();
        }


    }
}
  • 面包店:
  • 5个生产者,每个每次生产3个
  • 10个消费者,每个每次消费5个
  • 最大库存:100
  • 需求:面包师傅每个最多生产10次:
  • 消费者不再一直消费,把生产者生产完的面包消费完,就结束
  • 信息:面包店每天生产面包的最大数量:面包店每天生产5310=150个面包
  • 消费者,把150个面包消费完结束
public class BreadShop {
    /**
     * 生产者数量
     */
    private static int producerNum=5;

    /**
     * 每次生产个数
     */
    private static int onceBreadNum=3;

    /**
     * 每个生产者生产次数
     */
    private static int produceTimes=10;

    /**
     * 消费者数量
     */
    private static int consumerNum=10;

    /**
     * 每个消费者每次消费个数
     */
    private static int onceBuyNum=5;
    /**
     * 面包店最大库存
     */
    private static int COUNT=100;
    /**
     * 面包店当前库存
     */
    private static int currentCOUNT;
    /**
     * 生产面包总数
     */
    private static int breadTotal;
    /**
     * 生产者
     */
    public static class Producer implements Runnable{
        private String name;

        public Producer(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                //生产次数有限
                for (int i=0;i<produceTimes;i++) {

                    synchronized (BreadShop.class) {
                        if (currentCOUNT + onceBreadNum >COUNT) {
                            //库存已满,进入等待
                            BreadShop.class.wait();
                        } else {
                            currentCOUNT += onceBreadNum;
                            breadTotal += onceBreadNum;
                            System.out.printf("生产者:%s,生产了:%s次,库存:%s,生产面包总数:%s\n", name, i+1,currentCOUNT,breadTotal);
                            //此时可以生产了,就通知阻塞线程进入就绪态
                            BreadShop.class.notifyAll();
                            //模拟耗时
                            Thread.sleep(200);
                        }
                    }
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 消费者
     */
    public static class Consumer implements Runnable{
        private String name;

        public Consumer(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            try {
                while (true){
                    synchronized (BreadShop.class){
                            //生产面包总数达到最大也停止
                            if (breadTotal==producerNum*onceBreadNum*produceTimes){
                                break;
                            }
                            if (currentCOUNT-onceBuyNum<0){
                                //库存已空,无法消费
                                BreadShop.class.wait();
                            }else{
                                //库存未空可以消费
                                currentCOUNT-=onceBuyNum;
                                System.out.printf("消费者:%s,消费了:%s个面包,库存%s,\n",name,onceBuyNum,currentCOUNT);
                                //通知阻塞线程计入就绪态可以消费了
                                BreadShop.class.notifyAll();
                                //模拟耗时
                                Thread.sleep(200);
                            }
                    }
                    //模拟耗时
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        //同时启动20个消费者
        Thread[] consumers=new Thread[consumerNum];
        for (int i=0;i<consumerNum;i++){
            consumers[i]=new Thread(new Consumer(String.valueOf(i)));
        }
        //同时启动10个生产者
        Thread[] producers=new Thread[producerNum];
        for (int i=0;i<producerNum;i++){
            producers[i]=new Thread(new Producer(String.valueOf(i)));
        }

        for(Thread t:consumers){
            t.start();
        }
        for (Thread t:producers){
            t.start();
        }


    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值