情景题:生产者和消费者模型

该博客展示了如何使用Java实现一个基于数组的生产者消费者模型,利用ReentrantLock和Condition进行线程同步。代码中创建了两个线程,一个用于生产商品,另一个用于消费。测试部分启动了两个生产者线程和两个消费者线程,显示了多线程下生产与消费的交互过程。
摘要由CSDN通过智能技术生成

基于数组的形式实现了生产者与消费者的模型,代码如下:

public class ConsumerAndProducer {
    final Object[] items;// 生产队列
    int putIndex; //生产者指针
    int takeIndex; //消费者指针
    int count;//产品总数
    final ReentrantLock lock;//锁
    private final Condition notEmpty; //对应消费者的condition
    private final Condition notFull; //对应生产者的condition

    public ConsumerAndProducer(int capacity, boolean fair) {
        this.items = new Object[capacity];
        this.putIndex = 0;
        this.takeIndex = 0;
        this.count = 0;
        this.lock = new ReentrantLock(fair);
        this.notEmpty = lock.newCondition();
        this.notFull = lock.newCondition();
    }
    //生产产品
    public void put(Object obj) {
        //加锁保证线程安全
        lock.lock();
        //先判断此时生产队列是否已满
        try {
            while (count == items.length) {
                //阻塞生产者线程
                notFull.await();
            }
            System.out.println("正在生产第" + putIndex + "个商品");
            items[putIndex] = obj;
            //在越界时重置
            if (++putIndex == items.length) putIndex = 0;
            count++;
            //唤醒消费者线程
            notEmpty.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁,防止死锁
            lock.unlock();
        }
    }
    //消费者消费产品
    public Object take() {
        lock.lock();
        Object obj = null;
        try {
            while (count == 0) {
                //阻塞消费者线程
                notEmpty.await();
            }
            System.out.println("正在消费第" + takeIndex + "个商品");
            obj = items[takeIndex];
            items[takeIndex] = null;
            if(++takeIndex == items.length) takeIndex = 0;
            count--;
            //唤醒消费者进程
            notFull.await();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
            return obj;
        }
    }
}
class Producer implements Runnable{
    ConsumerAndProducer consumerAndProducer;

    public Producer(ConsumerAndProducer consumerAndProducer) {
        this.consumerAndProducer = consumerAndProducer;
    }

    @Override
    public void run() {
        try {
            for(int i =0; ; ) {
                //Thread.sleep(1);
                consumerAndProducer.put(new Object());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
class Consumer implements Runnable{
    ConsumerAndProducer consumerAndProducer;

    public Consumer(ConsumerAndProducer consumerAndProducer) {
        this.consumerAndProducer = consumerAndProducer;
    }

    @Override
    public void run() {
        try {
            for(int i = 0; ; ) {
                Thread.sleep(1);
                consumerAndProducer.take();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

测试:

@Test
    public void test5() {
        ConsumerAndProducer cap = new ConsumerAndProducer(50, false);
        Producer p = new Producer(cap);
        Consumer c = new Consumer(cap);
        new Thread(p).start();
        new Thread(p).start();
        new Thread(c).start();
        new Thread(c).start();
    }

输出:

正在生产第0个商品
正在生产第1个商品
正在消费第0个商品
正在消费第1个商品
正在生产第2个商品
正在生产第3个商品
正在生产第4个商品
正在生产第5个商品
正在生产第6个商品
正在生产第7个商品
正在生产第8个商品
正在生产第9个商品
正在生产第10个商品
正在生产第11个商品
正在生产第12个商品
正在生产第13个商品
正在生产第14个商品
正在生产第15个商品
正在生产第16个商品
正在生产第17个商品
正在生产第18个商品
正在生产第19个商品
正在生产第20个商品
正在生产第21个商品
正在生产第22个商品
正在生产第23个商品
正在生产第24个商品
正在生产第25个商品
正在生产第26个商品
正在生产第27个商品
正在生产第28个商品
正在生产第29个商品
正在生产第30个商品
正在生产第31个商品
正在生产第32个商品
正在生产第33个商品
正在生产第34个商品
正在生产第35个商品
正在生产第36个商品
正在生产第37个商品
正在生产第38个商品
正在生产第39个商品
正在生产第40个商品
正在生产第41个商品
正在生产第42个商品
正在生产第43个商品
正在生产第44个商品
正在生产第45个商品
正在生产第46个商品
正在生产第47个商品
正在生产第48个商品
正在生产第49个商品
正在生产第0个商品
正在生产第1个商品

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值