相同线程是一个并发模型,这种并发模型的含义是一个单线程的系统向外扩展成为N个单线程的系统。这个结果就是N个单线程的系统并行运行。
一个相同线程的系统不是一个纯粹的单线程系统,因为它包含了多个线程。但是这些线程中的每一个就像是一个单线程系统运行一样。
为什么是单线程的系统
今天你可能想知道为什么每一个都被设计成单线程系统呢。单线程系统已经得到普及,因为他们的并发模型比多线程更加简单。单线程系统不会跟其他线程共享任何数据。这个就使得线程去使用非并发的数据结构,以及更好的利用CPU和CPU缓存。
不幸的是,单线程系统不会充分利用现代CPU。一个现代的CPU经常会有2,4或者更多的内核。每一个内核的功能都可以作为一个单独的CPU。一个单线程系统只是利用了这些内核中的一个,如下图所示:
相同的线程,单线程的扩展
为了充分利用所有CPU的内核,一个单线程的系统可以向外扩展去利用整个的计算机。
每一个CPU一个线程
相同的线程系统通常都是在计算机中每一个CPU运行一个线程。如果这个计算机包括4个CPU,或者有4个内核的CPU,然后它将会标准的运行相同线程的4个实例(4个单线程系统),示意图如下:
没有共享的状态
一个相同的线程系统看起来跟多线程系统相似,因为一个相同的线程是有多个线程在内部运行的。但是这里有一个微妙的不同。
在相同的线程和一个多线程系统中的不同是在相同的线程的系统中没有共享的数据。这里没有线程同时访问的内存。没有并发的数据结构等等。不同如下图所示:
共享状态的减少是使得每一个线程表现为它是否是一个单线程的系统。然而,一个相同线程的系统可以包含不只是一个单线程,以至于它不是一个真正的“单线程系统”。缺乏一个更好的名字,我发现它更准确的去叫这样一个系统为相同线程的系统,而不是一个“拥有一个单线程设计的多线程系统”。相同的线程说起来非常简单,并且理解起来更简单。
相同的线程主要的意味着数据运行在相同的线程里面, 以及不会有共享数据。
负载分配
明显的,一个相同线程的系统需要共享给这个工作负载在运行的单个线程实例之间。如果不是,只有一个实例将会得到任何工作,并且这个系统将会实际上是单线程的。
怎么在不同的实例确切的分配负载取决于你的系统的设计。我将会在下面的部分覆盖一些。
单线程的微服务
如果你的系统包含了多个微服务,每一个微服务都可以运行在单线程模式下。当你部署多个单线程的微服务到相同的计算机上的时候,每一个微服务都可以在一个单独的CPU上运行一个单独的线程。
微服务不会共享任何数据,以至于微服务对于一个相同线程系统来说是一个好的使用案例。
有分片数据的服务
如果你的系统确实不需要共享数据,或者至少一个数据库,你可能能够去分片这个数据库。分片意味着这个数据被分开到了多个数据库中。这个数据是有代表性的分离的,以至于互相相关的数据位于相同的数据库中。例如,属于一些“owner”实体的所有数据将会插入到相同的数据库中。分片脱离了这个教程的范围,以至于你将会不得不查阅一些关于这个主题的一些教程。
线程通信
如果在相同线程中的线程需要通信,他们通过消息传递做这个。一个线程想发送一个消息给线程A,它可以通过生成一个消息去做这个(一个字节序列)。线程B然后可以拷贝和整个消息(字节序列),并且读取它。通过拷贝这个消息,线程B确定当它修改这个消息的时候,线程A是不能修改这个消息的。一旦它被拷贝了,对于线程A它是不可变的。
此过程示意图如下:
这个线程通信可以通过队列,管道,Unix套接字,TCP套接字代替。无论什么适合你的系统。
更简单的并发模型
每一个运行在它自己线程的系统如果它是单线程的可以使用相同的线程系统去实现。这就意味着相对有共享状态的线程来说内部并发模型变得更加简单了。你不需要担心并发的数据结构以及所有的并发问题。
插图
这里有一个单线程,多线程,相同线程系统的插图。你可以更简单的得到他们之间不同的一个概述
第一个图显示了一个单线程的系统:
第二图显示了一个多线程的系统,这里有共享数据:
第三张图显示了一个有分离数据的两个线程的相同线程系统,他们之间通过传递信息进行通信。
以上就是Java 相同的线程的内容,更多相关内容请关注PHP中文网(www.php.cn)!