【并发编程神器】,Worker Thread模式

简介: 【并发编程神器】,Worker Thread模式

何为WT模式,如何实现?


类比程序员的日常:办公室里执行 OKR 的程序员们,如果产品需求池有任务了,大家一起分任务,需求池空了(有生之年基本不会空)就摸鱼。

  • WT 中的 Worker Thread就是我们这些干活的程序员。

image.png

代码实现容易想到用阻塞队列做需求池,然后指定创建若干个线程消费阻塞队列中的任务。这就是线程池。

模式角色

  • Client (委托者)

Client创建表示工作请求的Request并将其传递给Channel。示例中由ClientThread扮演

1.png

  • Channel(通信线路)

Channel接收来自于Client的Request,并将其传递给Worke。示例程序中,由Channel扮演

1.png

  • Worker(工人)

Worker从Channel获取Request,并进行工作。当一项工作完成后,它会继续去获取另外的Request。示例中,由WorkerThread类扮演。、

image.png

  • Request (请求)

表示工作。Request 保存了进行工作所必需的信息。

1.png

image.png

image.png

image.png

该模式有什么好处呢?


提高吞吐量

将工作交给其他线程,自己就可以做别的工作。这是Thread-Per-Message模式的思想。

但由于启动新线程需要花费时间,所以WT模式的思想之一就是通过轮流、反复使用线程来提高吞吐量。

容量控制

可以同时提供的服务的数量,即容量控制:

Worker数量

Worker数量可自定义。示例中,传递给 Channel的构造函数的参数threads即表示这个数值。Worker会创建threads个 WorkerThread 实例。

Worker角色的数量越多,可以并发进行的处理也越多。但是,即使Worker角色的数量超过了 同时被请求的工作的数量,也不会对提高程序处理效率有什么帮助。因为多余的Worker角色不但不会工作,还会占用内存。增加容量就会增加消耗的资源,所以必须根据程序实际运行的环境调整Worker数量。


Worker数量不一定必须在程序启动时确定,也可以像下面这样动态地改变Worker角色 的数量。

  • 最开始只有几个Worker
  • 当工作增加时就增加Worker
  • 但若增加得太多会导致内存耗尽,因此到达极限值后就不再增加Worker
  • 反之,当工作减少(即等待工作的Worker角色增加)时,就要逐渐减少Worker角色

这些 JDK 线程池都实现好了。

Request 数量

Channel保存着Request。只要Worker不断工作,在Channel中保存的Request就不会增加很多。不过,当接收到的工作数量超出 Worker处理能力, Channel中就会积累很多Request。


这时,Client必须等待一段时间才能将Request发给Channel。示例的线程会在Channel类的putRequest方法中wait。


如果Channel角色可以保存很多Request角色,那么就可以填补(缓冲)Client角色与Worker 角色之间的处理速度差异。但是,保存Request角色会消耗大量的内存。因此,这里我们需要权衡 容量与资源。


调用与执行分离

对比Worker Thread模式中的【工作请求】与【普通的方法调用】

Client负责发送工作请求。它会将工作内容封装为Request,然后传给Channel。在普通的方法调用中,这部分相当于“设置参数并调用方法”:

  • 【设置参数】与【创建 Request】对应
  • 【传递给Channel】与【调用方法】对应


Worker负责工作。它使用从Channel接收到的Request执行实际处理。 在普通的方法调用中,这相当于【执行方法】。

在进行【普通的方法调用】时,“调用方法”和“执行方法”是连续进行的。因为调用方法后,方法会立即执行。在【普通的方法调用】中,调用与执行无法分离。


但在Worker Thread、Thread-Per-Message模式,方法的调用和方法的执行被有意分离。方法的调用被称为invocation (动词为invoke ),方法的执行则被称为execution (动词为 execute )。调用与执行的分离同时也是Command命令设计模式。


方法的invoke (调用)与execute (执行)是成对的。ExecutorService 接口的submit (提交)与 execute (执行)也是成对的。


调用和执行分离究竟有什么意义呢?

提高响应速度

如果调用和执行不可分离,那么当执行需要花费很长时间时,就会拖调用处理的后腿。但是如果将调用和执行分离,那么即使执行需要花费很长时间也没有什么关系,因为执行完调用处理的一方可以先继续执行其他处理,这样就可以提高响应速度。

控制执行顺序(调度)

如果调用和执行不可分离,那么在调用后就必须开始执行。

但是如果将调用和执行分离,执行就可以不再受调用顺序的制约。我们可以通过设置Request 优先级,并控制Channel将Request传递给Worker的顺序来实现上述处理。这 种处理称为请求调度(scheduling )。

可以取消和反复执行

将调用和执行分离后,还可以实现“即使调用了也可以取消执行”这种功能。

由于调用的结果是Request对象,所以既可以将Request保存,又可以反复地执行。

通往分布式

将调用和执行分离后,可以将负责调用的计算机与负责执行的计算机分离开来,然后通过网络将扮演Request对象从一台计算机传递至另外一台计算机。


Runnable接口的意义


Runnable接口有时会被用作Worker Thread模式中的Request。即该模式会创建一个实现 Runnable接口的类的实例(Runnable对象)表示工作内容,然后将它传递给Channel,让其完成这项工作。


Runnable对象可以作为方法参数传递,可以被放入到队列中,可以跨越网络传递,也可以被保存至文件中。然后,这样的Runnable对象不论被传递到哪台计算机中的哪个线程中,都可以运行。

这时,我们可以将Runnable接口看作GoF的Command模式中的Command角色。


目录
相关文章
|
8月前
|
搜索推荐
课时10:sublime的基本设置
今天,我们来聊聊如何对SublimeText进行简单的个性化配置。在使用SublimeText的过程中,很多人都会遇到一些问题,比如Sublime自带的字体不太好看,或者字体大小不符合个人需求,不是偏大就是偏小。接下来,我们就详细看看如何调整这些设置。 1.字体大小与样式调整 2.主题安装与配置
995 1
|
9月前
|
人工智能 算法 调度
DeepSeek杀疯了!国产AI大模型如何重构未来技术版图?
【爆款导读】当ChatGPT还在为每月10亿访问量沾沾自喜时,中国AI军团已悄然完成弯道超车。2025年开年,DeepSeek以雷霆之势横扫中美应用商店双榜,上线72小时突破千万DAU,开发者生态激增300%。通过优化算法降低成本、多模态能力提升效率,DeepSeek不仅在用户数量上取得突破,更在实际应用场景中展现强大实力。其开源策略推动技术民主化,助力更多开发者参与AI开发,成为AI军备竞赛中的佼佼者。
544 20
|
机器学习/深度学习 数据采集 自然语言处理
使用Python实现深度学习模型:智能社交媒体内容分析
使用Python实现深度学习模型:智能社交媒体内容分析
1041 69
|
机器学习/深度学习 人工智能 算法
【博士每天一篇论文-综述】Deep Echo State Network (DeepESN)_ A Brief Survey
本文是2017年C. Gallicchio和A. Micheli在ArXiv上发表的综述论文,详细介绍了深度回声状态网络(DeepESN)的架构、属性、动力学分析及其在时间序列预测等领域的应用,并探讨了DeepESN在处理多时间尺度信息方面的优势和潜力。
307 2
【博士每天一篇论文-综述】Deep Echo State Network (DeepESN)_ A Brief Survey
|
人工智能 自然语言处理 语音技术
《ModelScope:模型即服务的创新与未来》
【10月更文挑战第2天】** 本文深入探讨了 ModelScope 所代表的模型即服务(MaaS)模式的发展背景、核心特点、技术优势、应用场景以及对各个领域带来的深远影响。通过对其架构、功能和实际案例的分析,展现了 ModelScope 在推动人工智能发展、促进产业升级和创新方面的巨大潜力,同时也对其未来发展趋势进行了展望。
1002 1
|
SQL 存储 数据库
实验4:SQL视图操作技巧与方法
在数据库管理系统中,视图(View)是一种虚拟表,它基于SQL查询的结果集创建,并不实际存储数据
|
存储 缓存 监控
通用研发提效问题之动态调整干预能力,如何解决
通用研发提效问题之动态调整干预能力,如何解决
|
前端开发 Java
【Java项目】SpringBoot项目的多文件兼多线程上传下载
【Java项目】SpringBoot项目的多文件兼多线程上传下载
752 0
|
监控 数据挖掘 大数据
阿里云开源利器:DataX3.0——高效稳定的离线数据同步解决方案
对于需要集成多个数据源进行大数据分析的场景,DataX3.0同样提供了有力的支持。企业可以使用DataX将多个数据源的数据集成到一个统一的数据存储系统中,以便进行后续的数据分析和挖掘工作。这种集成能力有助于提升数据分析的效率和准确性,为企业决策提供有力支持。
|
负载均衡 应用服务中间件 PHP
使用nginx-haproxy实现七层负载均衡
【4月更文挑战第13天】使用nginx实现动静分离的负载均衡集群
310 4