# 《并发设计模式》第26章-生产者消费者模式-优化面向C端的个人文库系统

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★☆☆☆
  • 本章重点:了解生产者消费者模式的使用场景,掌握生产者消费者模式与多线程异步方式的区别,重点掌握生产者消费者模式在实际项目场景中的应用,并能够结合自身项目实际场景思考如何将生产者消费者模式灵活应用到自身实际项目中。

大家好,我是冰河~~

生产者消费者模式,在某些场景下,尽管并发请求量高,只要消费者的消费速度大于生产者的生产速度,则只需要少量的消费者线程即可处理对应的任务,不会过度的占用服务器资源。总之,生产者消费者模式可以使多个应用之间解耦,支持异步处理任务,平衡生产者和消费者之间的速度差异。

# 一、故事背景

在老王的耐心指导下,小菜初步基于线程池完成了对个人文库系统的优化,但是一想到老王说的个人文库项目的场景很适合使用生产者消费者模式来进行优化,小菜总想着如何基于生产者和消费者模式来优化系统,奈何自己功力不够,确实不知道该如何基于生产者消费者模式优化系统。于是,小菜便开始在网上找生产者消费者模式的实现案例,但大部分案例要么就是基于消息中间件实现,要么就是基于JDK中的阻塞队列实现,小菜也不确定使用哪种方式好。最终,还是决定请教老王。

# 二、寻求帮助

到底是基于消息中间件实现呢?还是基于JDK中的阻塞队列实现,小菜确实是无法确定使用哪种方式了,于是决定还是请教老王。他来到老王的工位旁,对老王说到:“老大,你之前说优化个人文库系统最好是使用生产者消费者模式,我在网上搜索生产者消费者模式的使用案例,有些是基于消息中间件实现,有些是基于JDK中的阻塞队列实现,那个人文库系统基于哪种方式实现呢?”。

老王停了,呵呵一笑说到:“基于哪种方式都可以,我给你讲讲怎么实现吧,使用生产者消费者模式优化个人文库系统,最好也考虑下两阶段终止协议”。

“好的,老大,那你再给我讲讲吧”。

“好,我们还是去会议室说”。

“好的”。

于是,小菜跟着老王再次走进了会议室。。。

# 三、优化分析

之前,初步基于线程池完成了对个人文库系统的优化,总体流程如图26-1所示。


但是这种方式有个弊端,如果并发量很高,线程池中的活跃线程数已达最大值,并且任务队列已满,此时再有新的任务到来时,就会触发拒绝策略。如果拒绝策略没选好,会影响用户体验,并且此时线程池处于高度饱和状态,CPU会频繁发生切换,在一定程度上也会引起系统的性能问题。

并且在对线程池进行调优时,如果线程数设置的太小,无法充分利用服务器的资源,提升并发性能。如果线程数设置的过大,就会造成CPU频繁切换,同样会引起性能问题。

对于像个人文库系统这种场景来说,最好的方式就是使用生产者消费者模式进行优化,那具体如何优化呢?其实,整体逻辑还是比较简单的,如图26-2所示。

# 查看全文

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码