前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个简单的生产者和消费者模型

一个简单的生产者和消费者模型

作者头像
在水一方
发布2023-05-23 14:44:06
1800
发布2023-05-23 14:44:06
举报
文章被收录于专栏:在水一方在水一方

一个简单的生产者和消费者模型

代码语言:javascript
复制
import java.util.LinkedList;

public class ProducerConsumerExample {

    public static void main(String[] args) throws InterruptedException {
        final Buffer buffer = new Buffer(5); // 创建一个缓冲区,容量为5

        // 创建一个生产者线程
        Thread producerThread = new Thread(() -> {
            try {
                int value = 0;
                while (true) {
                    buffer.put(value++); // 生产一个数据到缓冲区
                    Thread.sleep(1000); // 等待1秒钟
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 创建一个消费者线程
        Thread consumerThread = new Thread(() -> {
            try {
                while (true) {
                    int value = buffer.take(); // 从缓冲区中取出一个数据
                    System.out.println("Consumed: " + value);
                    Thread.sleep(2000); // 等待2秒钟
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // 启动生产者和消费者线程
        producerThread.start();
        consumerThread.start();

        // 等待线程结束
        producerThread.join();
        consumerThread.join();
    }

    // 缓冲区类
    static class Buffer {
        private final LinkedList<Integer> queue; // 用链表实现缓冲区
        private final int capacity; // 缓冲区容量

        public Buffer(int capacity) {
            this.queue = new LinkedList<>();
            this.capacity = capacity;
        }

        // 生产一个数据
        public void put(int value) throws InterruptedException {
            synchronized (queue) {
                while (queue.size() == capacity) { // 缓冲区已满,等待消费者消费
                    queue.wait();
                }
                queue.add(value);
                queue.notifyAll(); // 通知消费者可以消费了
            }
        }

        // 消费一个数据
        public int take() throws InterruptedException {
            synchronized (queue) {
                while (queue.isEmpty()) { // 缓冲区为空,等待生产者生产
                    queue.wait();
                }
                int value = queue.remove();
                queue.notifyAll(); // 通知生产者可以生产了
                return value;
            }
        }
    }
}

我们常用的 LinkedList 就可以当队列使用,实现了Dequeue接口,还有 ConcurrentLinkedQueue,他们都属于非阻塞队列

说明

创建了一个缓冲区类Buffer,它使用一个链表来实现缓冲区,并且具有生产和消费两个方法put()和take()。在put()方法中,如果缓冲区已满,就等待消费者消费;否则,将数据加入缓冲区,并通知消费者可以消费了。在take()方法中,如果缓冲区为空,就等待生产者生产;否则,从缓冲区中取出一个数据,并通知生产者可以生产了。

在main()方法中创建了一个缓冲区对象,并创建了一个生产者线程和一个消费者线程。生产者线程不断地生产数据,并将其放入缓冲区中;消费者线程不断地从缓冲区中取出数据,并打印出来。我们通过调整生产者和消费者的等待时间,可以观察到生产者和消费者之间的交互过程。

扩展

在多线程中阻塞队列的使用非常常见,例如LinkedBlockingQueue中就使用的不是synchronized关键字,而是用的ReentrantLock,结合Condition来用的,此时了解synchronized和lock的区别也就有必要了

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一个简单的生产者和消费者模型
  • 说明
  • 扩展
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档