JAVA多线程之四---同一线程化

流过昼夜 提交于 2019-11-27 20:17:53

同线程也是一种并发模型,指的是从单线程系统扩展中出N个单线程系统。 N个单线程在系统中并行运行。同线程不等于单线程,因为,它里面也包含着多个线程。 只是每个线程都像单线程那样运行。

单线程系统

      可能有人不理解,现如今怎么还有人设计一个单线程系统。 单线程系统流行,主要是应为它们的并发模型相对多线程系统来说更加简单。 单线程系统没有什么数据需要和其他线程共享使用。 这就让单个线程可以使用非并发的数据结构,而且还可以更好的利用CPU以及CPU内部缓存。但是,单线程系统并不能完全发挥出现代CPU的能力。现代CPU一般都有2核,4核或者更多内核。每个内核都是一个独立的CPU。 单线程系统只能利用一个内核。如图所示:

image

同线程,单线程扩展

       为了充分利用CPU中的所有内核,单线程系统可以进行扩展。

每个CPU一个线程

      同线程系统经常是每个CPU一个线程。 如果计算机有4个CPU,或者CPU有4个内核,那就运行4个相同的“单线程”。如图所示:

image

没有共享数据

     同线程系统中运行着多个线程,所以看起来类似一个多线程系统。 但是两个并不相等。区别就在于同线程系统中没有共享数据。 共享内存区域没有并发访问。没有并发型数据结构等等。如图所示:

image

没有共享数据,就可以让每个线程都可以像单线程系统那样运转。 同线程系统中虽然包含更多的线程,但并不是“单线程系统”。 这个名字可能并不十分准确,但至少“同线程”(Same-threaded)要比“单线程设计的多线程系统”(multi-threaded system with a single-threaded design)要好很多。同线程主要意味着,数据总是被同一个线程处理。同线程系统中不存在并发数据访问。

负载分配(调度)

    明显的,在同线程系统中需要在多个单线程实例之间进行负载分配。 如果不进行分配,可能导致所有工作都由一个实例处理,那这样就成了单线程系统了。如何恰当的调度,主要取决于系统设计。下面会介绍几种情况。

单线程微服务

       如果系统由多个微服务构成,每个微服务可以以单线程模型来运行。 当在同一个机器上,部署多个单线程的微服务,每个微服务可以在一个CPU上运行一个线程。微服务并不共享数据,因此微服务就是一个同线程系统的好例子。

带数据分片的服务

       如果系统避免不了共享数据,如只有一个数据库,那可以分片使用数据库。 分片意味着数据分布在多个数据库中。 在分片时把逻辑关联的数据放在一个数据库中。对于实例来说,就感觉数据都在一个数据库中。更多关于分片的资料,可以自行搜索。

线程通讯

       在同线程模型中,如果线程之间需要通讯,会在线程之间进行消息发送。 A线程想要发送消息给B线程,那A线程产生消息,然后B线程可以复制这个消息并读取。 通过复制消息,可以确保线程A不会在线程B读的时候修改数据。 这就类似不可变数据。如图所示:

image

线程通讯还可以通过队列,管道,unix sockets套接字,TCP通讯等等。

更简单的并发模型

        每个系统都已同线程的方式运行,那就可以以单线程的方式处理。 这就意味着内部并发模型可以更加简单。 那就无需担心并发数据结构等其他并发问题了。

示例

单线程系统

image

   多线程系统

image

同线程系统

image

Netty 4 的线程模型其实就是一个同线程系统

 

 转自 https://my.oschina.net/roccn/blog/1362847

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!