多线程小记

1 多线程目的

多线程开发的目的:为了提高 CPU 利用率(记住这个很重要)

2 多线程举例

2.1 任务A:

a1:访问数据库-耗时10ms
a2:计算数据1-耗时2ms
b1:访问文件-耗时10ms
b2:计算数据2-耗时2ms
c1:计算数据(前面获取的数据1和数据2)-耗时2ms

2.2 执行时间对比

如果用单线程

执行的时间是26ms(10+2+10+2+2),这个很好理解

如果用多线程

这个计算时间是有些复杂的,这里等下解释

理想情况下,机器是双核,同时不考虑超线程,这个时候把 a1+a2, b1+b2 分别放入单独的线程执行(记住 I/O 是不要占用 CPU 资源的)

执行时间是 14ms(10+2+2)

这里就体现出来了,高效利用 CPU,降低执行时间,当然是合理的利用多线程,好处多多,但也不要为了多线程而多线程,看下例(任务B):

2.3 任务B

a1:访问数据库-耗时2ms
a2:计算数据1-耗时2ms
b1:访问文件-耗时40ms
b2:计算数据2-耗时2ms
c1:计算数据(前面获取的数据1和数据2)-耗时2ms

单线程:48ms
多线程:44ms

这里多线程只比单线程节省了 4ms,而且这还是理想情况下,没有考虑到线程切换带来的损耗,如果线程切换损耗 2ms,那么使用多线程得不偿失,具体情况具体分析,当然谁也不会精确计算程序执行时间,这里需要在调试阶段或者日志记录中寻找瓶颈

3 多线程与 cpu 核数的关系

多线程只是为了提高 CPU 利用率,客观的说多线程是跟 CPU 核数是没有关系的,不要混淆概念,现代计算机的单 CPU 多核(相比较多 CPU 单核)都是为了提高计算效率,多线程跟 CPU 核数是没有关系的,单核和多核的区别就是并行了,这些就不写了。

总之多线程只是逻辑上的做事的方式,CPU 核数是提高效率的物理手段

4 超线程

超线程这个概念很有意思,上学的时候课本应该是有介绍的,请允许copy一段过来

4.2 概念

每个单位时间内,CPU只能处理一个线程(Thread)。除非有两个核心处理单元,否则要想在单位时间内处理超过一个的线程是不可能的。

超线程HT(Hyper-Threading)技术是在单个核心处理单元中集成两个逻辑处理单元,也就是一个实体内核(共享的运算单元),两个逻辑内核(有各自独立的处理器状态),从而可以在单位时间内处理两个分别进行整数和浮点运算的线程,模拟双内核运作。

4.2 例子

设一个进程要完成两个任务:任务 1 和任务 2,并且任务 1 要经历 A1àB1àC1 三个步骤才能完成,任务 2 要经历 A2àB2àC2 三个步骤才能完成。

①如果两个任务同步执行的话,完成两个任务是这样执行的:
花费时间段:

图片描述

这样从 A1 到 C2 只能一个一个地执行,当 A1 执行时,CPU 被占用,B1 到 C2 的线程只能等待,甚至当它们彼此之间并不竞争同一个资源时,也要等待前面的线程执行完毕后才能执行。

②如果两个任务异步执行的话,完成两个任务是这样执行的:
花费时间段:

图片描述

这样,任务1和任务2就分成两个独立的执行对象,也就是说: A1àB1àC1 和 A2àB2àC2是并发执行的。当 A1 在执行某个运算时,A2 线程可以去做其他的一些事情,比如访问磁盘等外部设备等。

对比①和②两种执行方式,完成所有任务,方式①需要 6 个时间段,而方式②只需要 3 个时间段,方式②所需时间是方式①的一半,所以方式②完成整个任务要快于方式①。

4.3 CPU 的发展简史

图片描述

5 综述

一句话记住多线程的目的即可,多线程最根本的本质就是为了提高 CPU 资源利用率。不同的时代机器的配置差异化还是很大,很多指标是很难统一量化,so 调试测试是手段,也仅仅是手段而已。

多线程编程涉及到的概念还是很多,这个以自己的业务为导向,设计出最适合当前业务的实施方式,一切从实际出发。


黑月亮
点滴记录,步步成长

现实与完美之间

1.6k 声望
24 粉丝
0 条评论
推荐阅读
centos | 修改静态 IP
设置 Centos 为使用静态 IP1 修改网络配置 {代码...} 修改后的内容如下 {代码...} 2 重启网络服务 {代码...} 3 查看地址 {代码...} 参考来源:[链接]

青阳半雪阅读 1.8k评论 3

开源C语言库Melon:I/O线程模型
本文展示开源C语言库Melon中的I/O线程模型。在Melon中存在三种线程模型,本篇仅对I/O线程模型进行说明。关于 Melon 库,这是一个开源的 C 语言库,它具有:开箱即用、无第三方依赖、安装部署简单、中英文文档齐全...

用户bPbzEjV阅读 821

封面图
全局视角看技术-Java多线程演进史
全文较长共6468字,语言通俗易懂,是一篇具有大纲性质的关于多线程的梳理,作者从历史演进的角度讲了多线程相关知识体系,让你知其然知其所以然。

京东云开发者1阅读 379

封面图
Runable和Callable的区别?你必须要搞清楚Thread以及FutureTask!
Runable与Callable的区别,据说是高频面试题,什么样的答案才会让面试官满意呢?所有java程序员都知道的答案是基于: {代码...} {代码...} 从Runable和Callable接口的定义我们就能知道的是:Runable接口的run方法...

阅读 536

BlockingQueue - 基于TransferStack的SynchronousQueue
ThreadPoolExecutor以BlockingQueue存储待执行任务,包括SynchronousQueue、LinkedBlockingQueue和ArrayBlockingQueue,今天的目的是源码角度深入研究SynchronousQueue。

阅读 488

开源C语言库Melon:多线程治理
这一需求乍看之下倒是有点类似supervisor在做的事情,每个功能一个单一后台进程。诚然进程是一个选择,但是实际使用中则会面临是大量的可执行程序和因人而异的开发风格。

用户bPbzEjV阅读 390

封面图
大哥,这是并发不是并行,Are You Ok?
​ 进程是操作系统进行资源分配的最小单位,其中资源包括:CPU、内存空间、磁盘IO等,同一进程中的多条线程共享该进程中的全部系统资源,而进程和进程之间是相互独立的。进程是具有一定独立功能的程序关于某个数据集合...

博学谷狂野架构师阅读 239

现实与完美之间

1.6k 声望
24 粉丝
宣传栏