生产者-消费者设计模式

一、生产者消费者设计模式

1、中间队列
一段内存空间,且可存取;

2、两种角色
(1)生产者:生产数据;
(2)消费者:消费数据。

3、三种关系
(1)生产者与生产者的互斥关系;
(2)消费者与消费者的互斥关系;
(3)生产者与消费者的互斥且同步关系。

二、实现方式

1、使用synchronized(wait()和notify())

2、使用Lock实现(await()和signal())

3、阻塞队列实现

三、生产者-消费者模型的优点

1、解耦:降低生产者和消费之间的依赖关系

2、支持并发
即生产者和消费者是两个可以独立的并发主体,互不干扰的运行,如果没有中间的环节,则会生产者阻塞或者消费者阻塞。不管是哪种方法效率都比较低。

3、支持盲闲不均
如果生产数据的速度时快时慢,缓冲区可以对其进行适当缓冲。当生产的数据太块时,消费者来不及处理,未处理的数据可以暂时存在缓冲区。等生产者的生产速度慢下来,消费者再慢慢处理掉。

四、提升与思考

1、队列可以有多种实现:
(1)先放先出:FIFO
(2)后放先出:LIFO
(3)优先级队列:Priority Queue

2、为什么生产和消费要用多线程
单线程太耗时,只有当多线程的效率提升可以抵消开发难度和性能消耗时才有必要用多线程;

3、别忘记sychronized和notifyAll()
否则其他线程一直等待,不会继续

4、生产线程和消费线程的数量匹配
上述问题可以只有一个生产线程和一个消费线程(PIPE模式)
当生产比较费时的时候生产线程多一些,消费耗时时(如网络IO)多一些消费线程(一对多对应线程池的WorkThread设计模式)

5、当生产者生产效率比较低时
可以增加生产者或者减少消费者

6、当消费者效率较高时
可以减少生产者或者增加消费者

五、基于单向链表的生产者消费者模型

1、我们这里用一个单链表当做那段共享内存,简单实现生产者消费者模型;

2、锁:同步的最常见方法是使用锁,锁是一种非强制机制,每一个线程在访问数据或资源之前先试图获取锁,并在访问结束之后释放锁,在锁已经被占用时试图获取锁,线程会等待,直到锁重新可用。

3、条件变量:
与互斥锁不同,条件变量是挂起等待而不是上锁,条件变量用来自动阻塞一个线程,直到某特殊情况的发生,通常条件变量和互斥锁同时使用。
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待”条件变量的条件成立”而挂起。
其次,线程可以唤醒条件变量,此时某个或多个等待此条件变量的线程都会被唤醒并继续支持。
条件的检测是在互斥锁的保护条件下进行的,如果一个条件为假,一个线程自动阻塞,并释放等待状态的互斥锁,如果一个线程改变了条件,与它关联的条件变量,唤醒一个或多个等待的线程,重新获得互斥锁,然后重新评价条件.如果两个线程共享读写的内存,条件变量可以实现这两个进程间的线程同步。

你可能感兴趣的:(每日一问,Java,生产者与消费者设计模式)