多线程_生产者与消费者

管程法(利用缓冲区解决)

管程法适用于生产与消费同时进行的模式

//测试:生产者消费者模型---管程法(利用缓冲区解决)
//wait() notifyAll()
//生产者 消费者 产品 缓冲区
public class Test01 {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        Provider provider = new Provider(container);
        Consumer consumer = new Consumer(container);

        new Thread(provider, "生产者01").start();
        new Thread(provider, "生产者02").start();
        new Thread(provider, "生产者03").start();
        new Thread(consumer, "消费者01").start();
        new Thread(consumer, "消费者02").start();
    }
}

//容器
class SynContainer {
    //容器大小
    int size = 100;
    //容器计数器
    int count = 0;

    //生产者放入产品
    public synchronized void push() throws InterruptedException {
        //如果容器满了 则等待消费者消费
        while (count >= size){                  //注:此处若是多线程 while判断无法替换为if
                                                //若是if判断 醒来后直接向下执行 不会判断此时容器是否由其他生产者线程填满 进而导致越界
                                                //而while循环在醒来后会重新执行一次while 若出现上述情况则让线程重新沉睡
            //通知消费者消费 生产者等待
            this.wait();
        }
        //已生产 通知消费者消费(唤醒沉睡的消费者线程)
        this.notifyAll();
        //生产
        count += 1;
    }

    //消费者消费产品
    public synchronized void pop() throws InterruptedException {
        while (count <= 0){
            //等待生产者生产 消费者等待
            this.wait();
        }
        //已消费 通知生产者生产(唤醒沉睡的生产者线程)
        this.notifyAll();
        //消费
        count -= 1;
    }
}

//生产者
class Provider implements Runnable{

    SynContainer container;

    public Provider(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(10);
                container.push();
                System.out.println("生产了编号为" + container.count + "的产品");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

//消费者
class Consumer implements Runnable{

    SynContainer container;

    public Consumer(SynContainer container) {
        this.container = container;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(10);
                container.pop();
                System.out.println("消费了编号为" + container.count + "的产品");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


信号灯法

信号灯法适用于生产和消费不同时进行的模式

//测试:生产者消费者模型---信号灯法(标识位)
public class Test02 {

    public static void main(String[] args) {

        Restaurant restaurant = new Restaurant();
        Cook cook = new Cook(restaurant);
        Diner diner = new Diner(restaurant);

        new Thread(cook, "厨师").start();
        new Thread(diner, "食客").start();

    }

}

class Cook implements Runnable {

    Restaurant restaurant;

    public Cook(Restaurant restaurant) {
        this.restaurant = restaurant;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(500);
                restaurant.cooking();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Diner implements Runnable{

    Restaurant restaurant;

    public Diner(Restaurant restaurant) {
        this.restaurant = restaurant;
    }

    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(500);
                restaurant.eating();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class Restaurant{
    boolean isCooking = true;

    int count = 1;

    public synchronized void eating() throws InterruptedException {
        while (isCooking) {
            this.wait();
        }
        System.out.println("已食用第" + count + "号菜品");
        isCooking = !isCooking;

        count++;
        notifyAll();
    }

    public synchronized void cooking() throws InterruptedException {
        while (!isCooking){
            this.wait();
        }
        System.out.println("已制作第" + count + "号菜品");
        isCooking = !isCooking;

        notifyAll();
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值