何为WT模式,如何实现?

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

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

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

模式角色

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

  • Channel(通信线路)
    Channel接收来自于Client的Request,并将其传递给Worke。示例程序中,由Channel扮演

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

  • Request (请求)
    表示工作。Request 保存了进行工作所必需的信息。


该模式有什么好处呢?

提高吞吐量

将工作交给其他线程,自己就可以做别的工作。这是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角色。

【并发编程神器】,Worker Thread模式相关推荐

  1. Java并发编程实战~Worker Thread模式

    在上一篇文章中,我们介绍了一种最简单的分工模式--Thread-Per-Message 模式,对应到现实世界,其实就是委托代办.这种分工模式如果用 Java Thread 实现,频繁地创建.销毁线程非 ...

  2. Java并发编程实战~生产者-消费者模式

    前面我们在<Worker Thread 模式>中讲到,Worker Thread 模式类比的是工厂里车间工人的工作模式.但其实在现实世界,工厂里还有一种流水线的工作模式,类比到编程领域,就 ...

  3. 多线程-并发编程(7)-生产者消费者模式及非阻塞队列与阻塞队列实现

    生产者消费者模式是一个十分经典的多线程协作模式 弄懂生产者消费者问题能够让我们对多线程编程的理解更加深刻 存在3个元素 1.生产者(类比厨师) 2.生产者的生产产品(类比美食) 3.消费者(类比吃货) ...

  4. java并发编程:设计原则与模式_java编程设计模式一——策略模式

    定义: 策略模式定义了算法族,分别封装起来,让它们之间相互替代.此模式让算法的变化独立于使用算法的客户. 问题描述: 建立一个鸭子Duck的父类,它有很多子类,Duck都会游泳,但是有鸭子会飞,有的鸭 ...

  5. Java并发编程的基础-Thread.interrupted

    通过interrupt,设置了一个标识告诉线程可以终止了,线程中还提供了静态方法Thread.interrupted()对设置中断标识的线程复位.比如在上面的案例中,外面的线程调用thread.int ...

  6. Java并发编程实战~Guarded Suspension模式

    Guarded Suspension 模式 比如,项目组团建要外出聚餐,我们提前预订了一个包间,然后兴冲冲地奔过去,到那儿后大堂经理看了一眼包间,发现服务员正在收拾,就会告诉我们:"您预订的 ...

  7. Java并发编程实战~Thread-Per-Message模式

    我们曾经把并发编程领域的问题总结为三个核心问题:分工.同步和互斥.其中,同步和互斥相关问题更多地源自微观,而分工问题则是源自宏观.我们解决问题,往往都是从宏观入手,在编程领域,软件的设计过程也是先从概 ...

  8. 腾讯架构师理解的并发编程基石——Thread类的工作原理

    1. 开篇词 说到并发编程,可能大家脑海中的第一印象会是 Thread.多线程.JUC.线程池.ThreadLocal 等等内容.确实,并发编程是 Java 编程中不可或缺的一部分,掌握并发编程的核心 ...

  9. Java多线程并发编程知识体系(附大图-持续更新)

    Java多线程体系 1.并发编程的优势 提升CPU资源利用率 提升吞吐量 提升程序响应速度 更好的编程模型 2.并发带来的问题 1.安全性问题 0.定义:什么是安全性问题 多线程读写共享变量时出现不正 ...

  10. 并发编程(1)学习攻略如何才能学好并发编程?

    并发编程并不是一门相对独立的学科,而是一个综合学科.并发编程相关的概念和技术看上非常零散,相关度也很低,总给你一种这样的感觉:我已经学习很多相关技术了,可还是搞不定并发编程.那如何才能学习好并发编程呢 ...

最新文章

  1. 阿里云 SSL 证书 总结
  2. 03-Windows Server 2016 IIS的安装与配置
  3. Windows平台编译Webkit
  4. 电子设计竞赛电源题(1)-电源题简介
  5. JAVA基础学习笔记(2)
  6. 开源推荐:Asp.Net Core入门学习手册!
  7. quick-cocos2d-x for mac开发环境安装配置
  8. SaCa DataViz 企业版 | 高性能大数据分析引擎
  9. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY‘RE NOT. RENEWALS ARE LESSER
  10. 图像识别讲解 以一个简单的图像识别任务为例
  11. jupyter notebook matplotlib绘制动态图并显示在notebook中
  12. python中的monkey-patching
  13. PHP简易留言板项目
  14. dell微型计算机换内存条,内存条的更换,详细教您电脑的内存条怎么更换
  15. json代码恶搞地图完整版qqxml地图卡片代码
  16. 如何将PDF转换成jpg图片?教你2种免费方法
  17. 《WiscKey: Separating Keys from Values in SSD-conscious Storage》阅读笔记
  18. MYSQL 数据库维护常识
  19. php ubound,VBA UBound()函数
  20. 贵金属软件MT4好不好用?MT4软件有什么优势特点?

热门文章

  1. 【分享】揭发天气秀、桌面秀、雪狐等号称资源占用小的桌面软件的流氓行为!
  2. 转载:BGA封装芯片手工焊接攻略
  3. Android Botton 事件
  4. 什么是DDL?其含义及其常用命令解析
  5. APT,EPT,ET,DPD含义与理解
  6. 腾讯应用宝市场的app 安全评估报告怎么写
  7. 【六】ubuntu发行版本构建工具
  8. python输出两个元素空格隔开_python实现将一串字符每两个一组,中间用空格隔开...
  9. 亮度对比度色调饱和度最佳_数码教程丨如何仿电影胶片色调与质感?
  10. security整合oauth2(jwt非对称加密):For MAC signing you do not need to specify the verifier key separately...