设计模式-生产者消费者模式 常见场景: 某个模块负责产生数据,这些数据由另一个模块来负责处理。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。 该模式还需要有一个缓冲区处于生
2017-09-08 00:02
671 查看
设计模式-生产者消费者模式
常见场景:某个模块负责产生数据,这些数据由另一个模块来负责处理。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据
缓冲区作用
1. 解耦,生产者和消费者只依赖缓冲区,而不互相依赖
2. 支持并发和异步
方式一,同步队列
/** * 生产者、消费者缓冲区 */ public class Storage implements IStorage { private final int maxSize = 10; private Queue<Object> queue = new LinkedList<Object>(); @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<Object> list = new LinkedList<Object>(); 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<Object> list = new LinkedBlockingQueue<Object>(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; } }
相关文章推荐
- 编写一个生产者,消费者多线程程序,一个线程随机产生数据,另一个线程显示所产生的数据.
- 架构设计:生产者/消费者模式[3]:环形缓冲区
- 生产者消费者问题 这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者
- 架构设计:生产者/消费者模式 第3页:队列缓冲区
- 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
- 架构设计:生产者/消费者模式 第3页:队列缓冲区
- 架构设计:生产者/消费者模式 第3页:队列缓冲区
- 架构设计:生产者/消费者模式[3]:环形缓冲区
- 架构设计:生产者/消费者模式 第6页:环形缓冲区的实现
- 架构设计:生产者/消费者模式 第3页:队列缓冲区
- 转:架构设计:生产者/消费者模式[3]:环形缓冲区
- 架构设计:生产者/消费者模式 第3页:队列缓冲区
- 架构设计:生产者/消费者模式 第6页:环形缓冲区的实现
- 架构设计:生产者/消费者模式 第5页:环形缓冲区
- 生产者消费者问题 这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者
- 生产者消费者问题 这是一个非常经典的多线程题目,题目大意如下:有一个生产者在生产产品,这些产品将提供给若干个消费者去消费,为了使生产者和消费者能并发执行,在两者之间设置一个有多个缓冲区的缓冲池,生产者
- 架构设计:生产者/消费者模式[2]:队列缓冲区
- 架构设计:生产者/消费者模式 第5页:环形缓冲区
- 架构设计:生产者/消费者模式 第6页:环形缓冲区的实现
- C++中提供了多种基本的数据类型。实际上,这些远不能满足我们的需求,如复数(第10章的例子大多是处理虚数的),再如分数。本任务将设计一个简单的分数类,完成对分数的几个运算。一则巩固基于对象编程的方法,