生产者-消费者模型 信号灯法

与管程法相比,信号灯法判断生产者(消费者)是否能能够放入(取出)产品的依据是标志位。

管程法则是通过容器是否有产品和是否超过容器容量等变量来判断。

打个比方,现在有一张桌子D,一个放苹果的人A(生产者),一个吃苹果的人B(消费者),以及苹果C。桌子可以放一个苹果。现在有个标志flag,当标志为true的时候,B才可以去吃,吃了后,标志位变为false,通知A再去放,如果B没有吃,A就一直等待。

以下是用java模拟的信号灯法的代码



import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;

/**
 * @ProductName:
 * @ProjectName:
 * @Package:
 * @Description: 生产者消费者 -信号灯法
 * @Author: 四叶总会来的
 * @Date: 2021/10/11 13:57
 * @UpdateRemark:
 * @Version: 1.0
 * <p>
 */
@Slf4j
public class ProduceAndConsumer1 {

    public static void main(String[] args) {
        Desk desk = new Desk(new Fruit("苹果"));
        Consumer1 consumer1 = new Consumer1(desk);
        Productor1 productor1 = new Productor1(desk);
        consumer1.start();
        productor1.start();
    }
}

/**
 * 生产者
 */
class Productor1 extends Thread {

    //生产产品
    /**
     *
     */
    Desk desk;

    /**
     *
     */
    public Productor1(Desk desk) {
        this.desk = desk;
    }

    @SneakyThrows
    @Override
    public void run() {
        while (true) {
            desk.putDesk(desk.fruit);
        }
    }
}

/**
 * 消费者
 */
class Consumer1 extends Thread {
    /**
     *
     */
    Desk desk;

    /**
     *
     */
    public Consumer1(Desk desk) {
        this.desk = desk;
    }

    @SneakyThrows
    @Override
    public void run() {
        while (true){
            desk.getDesk();
        }

    }
}

/**
 * 产品
 */
class Fruit {
    /**
     *
     */
    String name;

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

/**
 * 容器
 */
@Slf4j
class Desk {
    /**
     *
     */
    private Boolean flag = false;//true代表可以拿,false代表可以放
    /**
     *
     */
    public Fruit fruit;

    public Desk(Fruit fruit) {
        this.fruit = fruit;
    }

    public synchronized void putDesk(Fruit fruit) throws InterruptedException {

        if (flag == true) {
            log.info("已放入,等待中");
            this.wait();
        }
        log.info("我放了一个" + fruit.name);
        this.flag = true;
        this.notifyAll();
    }

    public synchronized void getDesk() throws InterruptedException {
        if (flag == false) {
            log.info("拿不了,等待中");
            this.wait();
        }

        log.info("我从桌子上拿了一个水果");
        this.flag = false;
        this.notifyAll();
    }


}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值