多线程通信---->管程法

时刻保持学习之心,方能成就不世功业
愿—>热爱编程的你,留下光辉之力;
通过生产者—<缓冲区>----消费者的模式,用管程法实现线程通信;

  • 生产者将生产的东西放入缓存区,通知消费者取走,消费者取走时,通知生产者再次生产;
  • 当缓存区有东西时,消费者未取走,则生产者不生产;停止生产并等待;直到东西被取走;
  • 如果场缓存区有产品,消费者将产品取走,否则停止消费并等待,知道有产品生成;
    我们使用一个简单的例子来实现它----->
// 通过生产者消费者模式,实现线程的通信---->管程法
//    情景:生产者(工产)、消费者(客人),产品(拉面);仓库(缓存区)
public class TestProducerConsumer {
    public static void main(String[] args) {
        WaresHouse waresHouse = new WaresHouse();
        Producer producer = new Producer(waresHouse);
        Consumer consumer = new Consumer(waresHouse);
        producer.start();
        consumer.start();
    }
}

//定义一个工厂类,工厂不仅一家
class Producer extends Thread {
    WaresHouse waresHouse;

    public Producer(WaresHouse waresHouse) {
        this.waresHouse = waresHouse;
    }

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            try {
                waresHouse.push(new Wares(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//定义一个消费类,消费者不止一个
class Consumer extends Thread {
    WaresHouse waresHouse;

    public Consumer(WaresHouse waresHouse) {
        this.waresHouse = waresHouse;
    }

    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            try {
                waresHouse.pop(new Wares(i));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//定义一个产品
class Wares {
    private int id; //产品编号

    public Wares(int id) {
        this.id = id + 1;
    }

    public int getId() {
        return id;
    }
}

//定义一个仓库(缓存区),因为仓库是固定的大小,所以我们应使用数组来做
class WaresHouse {
    Wares[] ware = new Wares[10];//仓库的大小固定
    int count = 0;//数组下表

    //    将产品放入仓库,不仅存放一次,需要保证线程同步
    public synchronized void push(Wares wares) throws InterruptedException {
//        waresHouses[count]=waresHouse;
//        判断容器是否被商品放满
        if (count == ware.length) {
//            仓库满了,通知消费者消费,生产等待
            this.wait();

        } else {
//            未满,将产品放入仓库
            ware[count] = wares;
            System.out.println("放置了第" + ware[count].getId() + "碗拉面");
            count++;
            this.notify();
        }
    }

    //    将产品取出仓库
    public synchronized void pop(Wares wares) throws InterruptedException {
        if (count == 0) {
//          等待生产者生产,消费者等待
            this.wait();

        } else {
            count--;
            System.out.println("吃了第" + ware[count].getId() + "拉面");
//            消费完,通知生产者生产;
            this.notify();
        }
    }
}

最后的运行结果

放置了第1碗拉面
放置了第2碗拉面
放置了第3碗拉面
放置了第4碗拉面
放置了第5碗拉面
放置了第6碗拉面
放置了第7碗拉面
放置了第8碗拉面
放置了第9碗拉面
放置了第10碗拉面
吃了第10拉面
吃了第9拉面
吃了第8拉面
吃了第7拉面
吃了第6拉面
吃了第5拉面
吃了第4拉面
吃了第3拉面
吃了第2拉面
吃了第1拉面
放置了第12碗拉面
放置了第13碗拉面
放置了第14碗拉面
放置了第15碗拉面
放置了第16碗拉面
放置了第17碗拉面
放置了第18碗拉面
放置了第19碗拉面
放置了第20碗拉面
放置了第21碗拉面
吃了第21拉面
吃了第20拉面
吃了第19拉面
吃了第18拉面
吃了第17拉面
吃了第16拉面
吃了第15拉面
吃了第14拉面
吃了第13拉面
吃了第12拉面
放置了第23碗拉面
放置了第24碗拉面
放置了第25碗拉面
放置了第26碗拉面
放置了第27碗拉面
放置了第28碗拉面
放置了第29碗拉面
放置了第30碗拉面
放置了第31碗拉面
放置了第32碗拉面
吃了第32拉面
吃了第31拉面
吃了第30拉面
吃了第29拉面
吃了第28拉面
吃了第27拉面
吃了第26拉面
吃了第25拉面
吃了第24拉面
吃了第23拉面
放置了第34碗拉面
放置了第35碗拉面
放置了第36碗拉面
放置了第37碗拉面
放置了第38碗拉面
放置了第39碗拉面
放置了第40碗拉面
放置了第41碗拉面
放置了第42碗拉面
放置了第43碗拉面
吃了第43拉面
吃了第42拉面
吃了第41拉面
吃了第40拉面
吃了第39拉面
吃了第38拉面
吃了第37拉面
吃了第36拉面
吃了第35拉面
吃了第34拉面
放置了第45碗拉面
放置了第46碗拉面
放置了第47碗拉面
放置了第48碗拉面
放置了第49碗拉面
放置了第50碗拉面
吃了第50拉面
吃了第49拉面
吃了第48拉面
吃了第47拉面
吃了第46拉面

很好的实现了,随即生产随即拿走,使用管程法;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值