博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-生产者消费者模式
阅读量:4979 次
发布时间:2019-06-12

本文共 3114 字,大约阅读时间需要 10 分钟。

常见场景:

某个模块负责产生数据,这些数据由另一个模块来负责处理。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。

该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据

 

缓冲区作用

1. 解耦,生产者和消费者只依赖缓冲区,而不互相依赖

2. 支持并发和异步

 

方式一,同步队列

/** * 生产者、消费者缓冲区 */public class Storage implements IStorage {    private final int maxSize = 10;    private Queue queue = new LinkedList();    @Override    public void put(Object obj) {        synchronized (queue) {            while (queue.size() > maxSize) {                System.out.println("缓冲区已满,不能进入");                try {                    queue.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            queue.add(obj);            System.out.println("进入缓冲区");            queue.notifyAll();        }    }    @Override    public Object get() {        Object obj = null;        synchronized (queue) {            while (queue.size() <= 0) {                System.out.println("缓冲区为空, 进入等待");                try {                    queue.wait();                } catch (InterruptedException e) {                    e.printStackTrace();                }            }            obj = queue.poll();            System.out.println("离开缓冲区");            queue.notifyAll();        }        return obj;    }}

 

 

方式二,可重入锁

public class Storage implements IStorage {    private final int maxSize = 20;    private LinkedList list = new LinkedList();    private final Lock lock = new ReentrantLock();    // 仓库满的条件变量    private final Condition full = lock.newCondition();    // 仓库空的条件变量    private final Condition empty = lock.newCondition();    @Override    public void put(Object obj) {        lock.lock();        while (list.size() >= maxSize) {            try {                System.out.println("缓冲区已满,不能进入");                // 生产阻塞                full.await();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        list.add(obj);        System.out.println("进入缓冲区");        empty.signalAll();        lock.unlock();    }    @Override    public Object get() {        lock.lock();        while (list.size() <= 0) {            try {                System.out.println("缓冲区为空, 进入等待");                // 消费阻塞                empty.await();            } catch (InterruptedException e) {                e.printStackTrace();            }        }        Object obj = list.remove();        System.out.println("离开缓冲区");        full.signalAll();        lock.unlock();        return obj;    }}

 

 

方式三,阻塞队列

public class Storage implements IStorage {    private LinkedBlockingQueue list = new LinkedBlockingQueue(10);    @Override    public void put(Object obj) {        try {            list.put(obj);        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("进入缓冲区");    }    @Override    public Object get() {        Object obj = null;        try {            obj = list.take();        } catch (InterruptedException e) {            e.printStackTrace();        }        System.out.println("离开缓冲区");        return obj;    }}

 

转载于:https://www.cnblogs.com/alex09/p/6675664.html

你可能感兴趣的文章
学习Memcached
查看>>
排序算法 学习
查看>>
xml
查看>>
ubuntu kylin 13.10 无法安装ia32-libs解决方案
查看>>
mac下安装mysql教程
查看>>
去掉关闭按钮同时禁用alt+f4进行关闭
查看>>
HBase API操作
查看>>
Linux文件属性之文件权限介绍
查看>>
Linux命令之---which简单介绍
查看>>
java接口和抽象类
查看>>
大型网站优化-memcache技术
查看>>
How to support comparators in our sort implementations?
查看>>
微信网页版前端源码分析(一)源码结构和公众号处理逻辑
查看>>
数据库基础知识
查看>>
第一部分绪论 第一章
查看>>
【bzoj4987】Tree【树形dp】
查看>>
iontify
查看>>
Vue.$nextTick用途
查看>>
数组<-->变量
查看>>
10101 : 正面交锋
查看>>