图解Java多线程设计模式

本文介绍了并发编程中的关键模式,如生产者-消费者模式、读写锁模式、每条消息一个线程模式、WorkerThread模式、Future模式、两阶段终止模式以及线程特定存储模式,最后强调了ActiveObject模式作为各种模式的综合,它在实际编程中的应用和重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第5章Producer-Consumer模式

Producer是生产者的意思,指的是生成数据的线程。Consumer则是"消费者"的意思,指的是使用数据的线程。生产者安全地将数据交给消费者。但当虽然仅是这样看似简单的操作,

但当生产者和消费者以不同的线程运行时,两者之间的处理速度差异便会引起问题。例如,消费者想要获取数据,可数据还没生成,或者生产者想要交付数据,而消费者的状态还无法接收数据等。Producer-Consumer模式在生产者和消费者之间加入了一个

“桥梁角色”。

该桥梁角色用于消除线程间处理速度的差异。一般来说,在该模式中,生产者和消费者都有多个,当然生产者和消费者有时也会只有一个。当两者都有一个时,我们称为Pipe模式。

第 6 章 Read-Write Lock 模式

6.1 Read-Write Lock模式

学生们正在一起看老师在黑板上写的板书。这时,老师想擦掉板书,再写新的内容。而学生们说道:“老师,我们还没看完,请先不要擦掉!”于是,老师就会等待大家都看完。

本章,我们将学习Read-Write Lock 模式。

当线程“读取”实例的状态时,实例的状态不会发生变化。实例的状态仅在线程执行“写入”操作时才会发生变化。从实例的状态变化这个观点来看,“读取”和“写入”有着本质的区别。

在Read-Write Lock模式中,读取操作和写入操作是分开考虑的。在执行读取操作之前,线程必须获取用于读取的锁。而在执行写入操作之前,线程必须获取用于写入的锁。

由于当线程执行读取操作时,实例的状态不会发生变化,所以多个线程可以同时读取。但在读取时,不可以写入。当线程执行写入操作时,实例的状态就会发生变化。因此,当有一个线程正在写入时,其他线程不可以读取或写入。

一般来说,执行互斥处理会降低程序性能。但如果把针对写入的互斥处理和针对读取的互斥处理分开来考虑,则可以提高程序性能。

第7章 Thread-Per-Message模式

7.1 Thread-Per-Message模式

上司把文件递给下属:“能帮我传真一下这个文件吗?”妻子告诉丈夫:“老公,帮忙倒一下垃圾”。像这样将工作委托给其他人的情况很常见。这个人把工作拜托给别人之后,就可以返回继续做自己的工作。

本章,我们将学习 Thread-Per-Message 模式。

所谓 Per,就是“每~”的意思。因此,Thread Per Message 直译过来就是“每个消息一个线 程”的意思。Message在这里可以理解为“命令”或“请求”。为每个命令或请求新分配一个线程, 由这个线程来执行处理——这就是Thread-Per-Message模式。

在 Thread-Per-Message 模式中,消息的“委托端”和“执行端”是不同的线程。消息的委托端线程会告诉执行端线程“这项工作就交给你了”。

第 8章 Worker Thread 模式

8.1 Worker Thread 模式

这是一个来自工作车间的故事。在这里,工人们负责组装塑料模型。客户会将很多装有塑料模型的箱子带到工作车间来,然后摆放在桌子上。

工人必须将客户送过来的塑料模型一个一个组装起来。他们会先取回放在桌子上的装有塑料模型的箱子,然后在阅读了箱子中的说明书后开始组装。当一箱模型组装完成后,工人们会继续去取下一个箱子。当所有模型全部组装完成后,工人们会等待新的模型被送过来。

本章,我们将学习 Worker Thread 模式。

Worker 的意思是工作的人、劳动者。在 Worker Thread 模式中,工人线程(worker thread )会 逐个取回工作并进行处理。当所有工作全部完成后,工人线程会等待新的工作到来。

Worker Thread 模式也被称为Background Thread (背景线程)模式。另外,如果从“保存多个 工人线程的场所”这一点来看,我们也可以称这种模式为Thread Pool (线程池)模式。

第9章 Future 模式

9.1 Future 模式

假设我们去蛋糕店买蛋糕。下单后,店员一边递给我们提货单,一边说“请您傍晚再来取蛋糕”。到了傍晚,我们就拿着提货单去取蛋糕。这时,店员会先和我们说“您的蛋糕已经做好了”,然后将蛋糕递给了我们。

本章,我们将学习 Future 模式。

Future 的意思是未来、期货(经济学用语)。假设有一个方法需要花费很长时间才能获取运行结果。那么,与其一直等待结果,不如先拿一张“提货单”。获取提货单并不耗费时间。这里的“提货单”我们就称为 Future 角色。

获取 Future 角色的线程会在稍后使用 Future角色来获取运行结果。这与凭着提货单去取蛋糕非常相似。如果运行结果已经出来了,那么直接领取即可;如果运行结果还没有出来,那么需要等待结果出来。

Future 角色是购买蛋糕时的提货单、预购单、预约券,是“未来”可以转化为实物的凭证。建议大家在阅读本章之前先学习Thread-Per-Message模式(第7章)的相关知识。

第10章 Two-Phase Termination 模式

10.1 Two-Phase Termination模式

小孩子在玩玩具时经常会将玩具弄得满房间都是。晚上到了睡觉时间,妈妈就会对小孩子说:“先收拾房间再睡觉哦。”这时,小孩子会开始打扫房间。

本章,我们将学习Two-Phase Termination模式。

该模式的名字直译为中文是“分两阶段终止”的意思。它是一种先执行完终止处理再终止线程的模式(图 10-1)。

我们称线程在进行正常处理时的状态为“操作中”。在要停止该线程时,我们会发出“终止请求”。这样,线程就不会突然终止,而是会先开始进行“打扫工作”。我们称这种状态为“终止处理中”。从“操作中”变为“终止处理中”是线程终止的第一阶段。

在“终止处理中”状态下,线程不会再进行正常操作了。它虽然仍然在运行,但是只会进行终止处理。终止处理完成后,就会真正地终止线程。“终止处理中”状态结束是线程终止的第二阶段。

先从“操作中”状态变为“终止处理中”状态,然后再真正地终止线程。这就是Two-Phase

Termination 模式。

该模式的要点如下。

安全地终止线程(安全性)

必定会进行终止处理(生存性)

发出终止请求后尽快进行终止处理(响应性)

第11章 Thread-Specific Storage 模式

11.1 Thread-Specific Storage模式

有一个储物间,里面并排摆放着许多储物柜。一个人拿着自己的钥匙进入了储物间,出来时手上拿着自己的行李。别人也拿着自己的钥匙进入了储物间。但是,虽然进入的是同一个储物间,打开的当然是另外一个储物柜。使用者都会从各自的储物柜中取出自己的行李。

本章,我们将学习 Thread-Specific Storage 模式。

Specific是“特定的”的意思,Storage是储存柜、存储装置的意思。因此,所谓ThreadSpecific Storage 就是“每个线程特有的存储柜”“为每个线程准备的存储空间”的意思。

Thread-Specific Storage 模式是一种即使只有一个人口,也会在内部为每个线程分配特有的存储 空间的模式。

Thread-Specific Storage模式还有以下名称。

Per-Thread Attribute(线程各自的属性)

在Java标准类库中,java,lang,ThreadLocal类实现了该模式。

12.Active Object 模式

12.1 Active Object 模式

在公司里,许多人都在工作着。有接待人员、销售人员、生产产品的工人、管理人员,还有负责发货和搬运产品的人……正是这些各个岗位上的人们互相协作,公司才能正常运营。如果将公司看作一个整体,它就是一个具有人格的组织——法人。

本章,我们将学习 Active Object 模式。

Active 是“主动的”的意思,因此 Active Object 就是“主动对象”的意思。所谓“主动的”, 一般指“有自己特有的线程”。因此,举例来说,Java的java.lang.Thread类的实例就是一种主动对象。

不过,在 Active Object 模式中出场的主动对象可不仅仅“有自己特有的线程”。它同时还具有可以从外部接收和处理异步消息并根据需要返回处理结果的特征。

消息。Active Object 模式中的主动对象会通过自己特有的线程在合适的时机处理从外部接收到的异步

在 Active Object模式中,组成主动对象与许多自然人组成法人类似。即使是Java 语言这样没有异步消息的编程语言,也可以使用 Active Object 模式组成实际上能够处理异步消息的主动对象。

Active Object模式综合了 Producer-Consumer模式(第 5 章)、Thread-Per Message 模式(第 7章)、 Future模式(第9 章)等各种模式。因此,建议大家在开始阅读本章之前,先阅读其他相关章节。

Active Object 模式有时也被称为Actor 模式 和 Concurrent Object 模式。

本书浅显易懂的介绍了JAVA线程相关的设计模式,通过程序范例和UML图示来一一解说,书中代码的重要部分加了标注以使读者更加容易理解,再加上图文并茂,对于初学者还是程序设计高手来说,这都是一本学习和认识JAVA设计模式的一本好书。(注意,本资源附带书中源代码可供参考) 多线程与并发处理是程序设计好坏优劣的重要课题,本书通过浅显易懂的文字与实例来介绍Java线程相关的设计模式概念,并且通过实际的Java程序范例和 UML图示来一一解说,书中在代码的重要部分加上标注使读者更加容易解读,再配合众多的说明图解,无论对于初学者还是程序设计高手来说,这都是一本学习和认识设计模式非常难得的好书。 书中包含Java线程的介绍导读、12个重要的线程设计模式和全书总结以及丰富的附录内容。第一章相关线程设计模式的介绍,都举一反三使读者学习更有效。最后附上练习问题,让读者可以温故而知新,能快速地吸收书中的精华,书中最后附上练习问题解答,方便读者学习验证。 目录 漫谈UML UML 类图 类和层次结构的关系 接口与实现 聚合 访问控制 类间的关联性 顺序图 处理流程和对象间的协调 时序图 Introduction 1 Java语言的线程 Java语言的线程 何谓线程 明为追踪处理流程,实则追踪线程 单线程程序 多线程程序 Thread类的run方法和start方法 线程的启动 线程的启动(1)——利用Thread类的子类 线程的启动(2)——利用Runnable接口 线程的暂时停止 线程的共享互斥 synchronized方法 synchronized阻挡 线程的协调 wait set——线程的休息室 wait方法——把线程放入wait set notify方法——从wait set拿出线程 notifyAll方法——从wait set拿出所有线程 wait、notify、notifyAll是Object类的方法 线程的状态移转 跟线程有关的其他话题 重点回顾 练习问题 Introduction 2 多线程程序的评量标准 多线程程序的评量标准 安全性——不损坏对象 生存性——进行必要的处理 复用性——可再利用类 性能——能快速、大量进行处理 评量标准的总结 重点回顾 练习问题 第1章 Single Threaded Execution——能通过这座桥的,只有一个人 第2章 Immutable——想破坏它也没办法 第3章 Guarded Suspension——要等到我准备好喔 第4章 Balking——不需要的话,就算了吧 第5章 Producer-Consumer——我来做,你来用 第6章 Read-Write Lock——大家想看就看吧,不过看的时候不能写喔 第7章 read-Per-Message——这个工作交给你了 第8章 Worker Thread——等到工作来,来了就工作 第9章 Future——先给您这张提货单 第10章 Two-Phase Termination——快把玩具收拾好,去睡觉吧 第11章 Thread-Specific Storage——每个线程的保管箱 第12章 Active Object——接受异步消息的主动对象 总结 多线程程序设计的模式语言 附录A 练习问题的解答 附录B Java的内存模型 附录C Java线程的优先级 附录D 线程相关的主要API 附录E 参考文献
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值