线程门(thread gate)模式是控制线程并发的一个有效工具,但是很多开发者对它并不熟悉。如同交通信号灯可以让汽车在十字路口有序通行一样,线程门可以根据给定条件阻止或允许线程执行。Obi Ezechukwu在本文中为我们介绍了线程门的概念,然后通过一个一个多线程素数生成器告诉我们如何使用它。
多线程和并发编程曾经是编程高手们才涉足的领域,但是随着多核处理器的出现,以及应用程序需求的更复杂,还有javax.util.concurrent包的出现,这种情况已经发生了变化。现在,企业应用开发者需要了解Java语言中不同的并发机制和构思。当面临需要非教科书式、高度创新的并发构思才能解决的问题时,这种需求更显迫切。这种情形下,仅仅理解Java语言和标准SDK的并发机制已经不能满足需要;你必须能够使用这些工具来编写程序,实现定制化的并发控制。
在本篇文章中,我们将了解一个人们较少讨论的并发模式,通常被称为线程门。如同现实世界中门的概念一样,门实例可以打开或关闭,从而实现允许或阻止线程执行。它基于某些判定式的真值来实现这个操作。
下面我将大体介绍一下基于通信流模型的线程门,然后解释一下如何建立示例应用(一个多线程素数生成器)的开发环境。文章的剩余部分将通过实例方式让你了解线程门模式。
线程门概述
与线程门非常类似的一个例子是运行在很多十字路口的交通信号灯系统。当红灯亮的时候,汽车必须停车等候,直到信号改变;当绿灯亮的时候,汽车可以自由通行。 交通信号灯被设计用来实现交通的交叉进行,在不需要交叉通行的地方它是没有用武之地的。对于程序员来说,你可以把交通信号灯看作控制器,它可以让双向交通共享使用同一小部分道路,如果没有它,交通线路交叉的地方将是一个非常危险的地方。
同样,线程门通常最适合的情况是:当一个线程集处于激活状态时,其它线程不能被执行。换句话说,相互竞争的线程集依赖于某些真值判定式的值,判定式的每一个不同的值只触发一个线程集,而强制其它处于挂起状态。注意此处的重点是针对一系列或一组线程而并非单个线程。实际上,我们关注的重点是多个线程共享访问一个底层资源的情形,而且这些线程根据对资源所执行的操作,被划分成不同的集合。
很好的一个例子是生产者—消费者(producer-consumer)流程,某些线程负责制造另一组线程所使用的数据;共享资源最可能是不同线程集所使用的切换机制(数据总线);而决定线程处理的真值判定式是数据量。如果数据作为一个与生产过程类似的流程部分被进行入队操作,然后该数据被不同过程使用或进行出队操作,一个内存请求队列有时候可能适合此类模式。
生产者-消费者模型是描述线程门概念使用的一个很好例子。对于绝大多数程序员来说,通过一个示例程序或许能够更轻松理解一个概念。在本篇文章中,问题还应该是如何轻松的实现任务分解和并行操作,因为重点是对其创建一个多线程解决方案。本篇文章的示例应用将实现上述目标。