5.同线程(Same-threading)

● 为什么使用单线程系统?

● 同线程:单线程横向扩展

    ○ 每个CPU一个线程

● 没有共享状态

● 负载分配

    ○ 单线程微服务

    ○ 分片数据服务

● 线程通信

● 更简单的并发模型

● 插图

● Thread Ops for Java工具包


同线程(Same-threading)是一种单线程系统扩展到N个单线程系统的并发模型, 其结果是N个并行运行的单线程系统。

一个同线程的系统并不是一个纯粹的单线程系统,因为它包含多个线程。 但是-每个线程都像单线程系统一样的运行。 因此,我们使用术语“同线程(Same-threading)”而不是“单线程”。

为什么使用单线程系统?

你可能想知道为什么今天还有人设计单线程系统。 单线程系统之所以流行,是因为它们的并发模型比多线程系统简单得多。 单线程系统不与其他线程共享任何状态(对象/数据)。 这使得单线程可以使用非并发数据结构,并更好地利用CPU和CPU缓存。

不幸的是,单线程系统不能完全利用现代CPU。 现代CPU通常会有2、4、6、8或者更多的内核。 每个内核都可以当成一个单独的CPU使用。 单线程系统只能利用其中一个内核,如下所示:

单线程系统只能利用一个CPU内核

同线程:单线程横向扩展

为了利用CPU中的所有内核,可以扩展单线程系统以利用整个计算机。

每个CPU一个线程

同线程系统通常在计算机中每个CPU运行1个线程。 如果计算机包含4个CPU或具有4个内核的CPU,则通常会运行4个同线程系统实例的线程(4个单线程系统)。 下图说明了这一原理:

同时运行4个同线程系统实例

没有共享状态

一个同线程的系统,看起来类似于传统的多线程系统,因为一个同线程系统的内部有多个线程在运行。 但是同线程系统与多线程系统之间也有细微的差别。

同线程系统与传统多线程系统之间的区别在于,同线程系统中的线程不共享状态。 没有线程并行访问的共享内存。 没有线程共享数据的并发数据结构等。 下图展示了这种差异:

同线程系统与传统多线程系统之间的区别

缺少共享状态,导致每个线程看上去就像是单线程系统下的行为一样。 但是,由于一个同线程的系统可以包含多个线程-它实际上不是“单线程系统”。 由于缺乏更好的名称,我发现将这样的系统称为同线程系统而不是“具有单线程设计的多线程系统”更为精确。 同线程更容易说,也更容易理解。

从本质上讲,同线程意味着数据处理与其线程处于同一线程内部,并且同线程系统中不会有多个线程同时操作共享数据。 有时,这也被称为无共享状态并发或分离状态并发。

负载分配

显然,一个同线程系统需要在运行的单线程实例之间共享工作负载。 如果只有一个线程完成所有工作,则该系统实际上将是单线程的。

究竟如何在不同线程上分配负载,这取决于系统的设计。 我将在以下各节中介绍一些相关内容。

单线程微服务

如果你的系统包含多个微服务,则每个微服务都可以使用单线程模式运行。 当你将多个单线程微服务部署到同一台计算机上时,每个微服务都可以在单个CPU上运行一个单线程。

微服务本质上不共享任何数据,因此微服务是同线程系统的一个很好的用例。

分片数据服务

如果你的系统确实需要共享数据,或者至少需要共享一个数据库,则可以对数据库进行分片。 分片意味着将数据划分到多个数据库中。 通常对数据进行划分,以使彼此相关的所有数据都位于同一数据库中。 例如,属于某个“所有者”实体的所有数据都将插入到同一数据库中。 但是,分片不在本教程的讨论范围之内,因此您必须搜索有关该主题的教程。

线程通信

如果一个同线程系统中的线程需要进行通信,则它们可以通过消息传递来进行通信。 如果线程A要向线程B发送消息,则线程A可以通过生成消息(字节序列)来发送消息。 然后,线程B可以复制该消息(字节序列)并读取它。 通过复制消息,线程B确保线程A在读取消息时无法修改消息。 复制后,线程A无法访问该消息副本。

通过消息传递进行的线程通信如下图所示:

通过消息传递进行线程通信

线程通信可以通过队列、管道、Unix套接字、TCP套接字等进行,你可以从中选择一个适应你系统的通信方式。

更简单的并发模型

在一个同线程系统中,在自己的线程中运行的每个系统都可以像单线程一样实现。 这意味着内部并发模型变得比线程共享状态简单得多, 您不必担心并发数据结构以及此类数据结构可能导致的所有并发问题。

插图

这是单线程、多线程和同线程系统的图示,因此您可以更轻方便了解它们之间的区别。

第一个插图显示了单线程系统。

单线程系统

第二个图显示了一个多线程系统,其中线程之间共享数据。

多线程系统

第三幅图显示了一个具有2个线程,且各自具有独立数据的同线程系统,它们通过相互传递消息进行通信。

同线程系统

Thread Ops for Java工具包

Thread Ops for Java是一个开源工具包,旨在帮助你更轻松地实现分离状态的同线程系统。 线程操作包含用于启动和停止单个线程以及通过单个线程实现某种程度的并发性的工具。 如果你对使用同线程的应用程序设计感兴趣,那么Thread Ops对于你来说 ,看起来可能很有趣。 你可以在我的Thread Ops for Java教程中阅读有关线程操作的更多信息。


译自:Same-threading

Jakob Jenkov

Last update: 2019-12-07

你可能感兴趣的:(5.同线程(Same-threading))