首先,我们要搞懂两个问题:

  1. 为什么要使用多线程?
  2. 多线程的应用场景有哪些?

♣ 为什么要使用多线程?

使用多线程本质上是提升程序性能。那么衡量性能的指标又包括哪些?

  1. 延迟:延迟是指发出请求到收到响应这个过程的时间。延迟越短,意味着程序执行的越快,性能越好。
  2. 吞吐量:吞吐量指的是单位时间内能处理请求的数量。吞吐量越大,意味着程序能处理的请求越多,性能越好。

我们所谓提升性能,主要是降低延迟,提高吞吐量。要想实现这个目的,先要了解多线程的使用场景。

♣ 多线程的应用场景

在并发编程领域,提升性能本质就是提升硬件的利用率,也就是提升 I/O 和 CPU 利用率。操作系统解决硬件利用率问题的对象往往是单一硬件设备,而并发程序往往需要 CPU 和 I/O 设备相互配合工作,所以我们要考虑 CPU 和 I/O 设备综合利用率的问题。

下面我们看看多线程是如何提升 CPU 和 I/O 利用率的。假设程序按照 CPU 计算和 I/O 操作交叉执行的方式运行,而且 CPU 计算和 I/O 操作的耗时是 1:1.

如图,当只有一个线程,执行CPU计算时,I/O设备空闲;执行I/O操作时,CPU空闲。所以两者利用率都是50%。
                 
如果又增加一个线程,如图,线程A执行 CPU 计算时,线程B执行 I/O 操作;线程B执行 CPU 计算时,线程A执行 I/O 操作;这样 CPU 和 I/O 设备的利用率就达到了 100%。
                 
刚刚我们将 CPU 和 I/O 设备的利用率都提升到了100%,单位时间处理的请求数量翻了一倍,也就是说吞吐量提高了1倍。反过来想:如果CPU 和 I/O 设备的利用率都很低,那么可以尝试通过增加线程来提高吞吐量

单核CPU时代,多线程主要是用力啊平衡 CPU 和 I/O 设备的。如果程序只有CPU计算,而没有I/O操作,多线程不会使性能提升反而会下降,原因是多线程增加了线程切换的成本。不过在多核时代,这种纯计算型的场景可以利用多线程提升性能,因为利用多核可以降低响应时间。

举个例子:
计算 1+2+…+100亿的值,如果用4核CPU的程序执行,A线程计算(1,25亿),B线程计算(25亿,50亿),C线程计算(50亿,75亿),D线程计算(75亿,100亿),最后汇总。这样理论上会比一个线程计算[1,100亿]快4倍左右,响应时间能够降低到25%。一个线程,对于4核的CPU,利用率只有25%,而4个线程,则能够将CPU的利用率提高到100%。

                 

♣ 创建多少线程合适?

创建多少线程才是合适的,要看多线程具体的应用场景。一般有两种情况:

  1. I/O密集型
  2. CPU密集型

I/O密集型程序和CPU密集型程序,计算最佳线程数的方法不同。
下面我们分开来说。

♠ CPU密集型

对于CPU密集型计算,多线程本质上是提升CPU的利用率,所以对于一个4核的CPU,每个核一个线程,理论上创建4个线程就可以了,再多创建线程也只会增加线程切换成本。所以,对于CPU密集型的计算场景,理论上“线程数量 = CPU 核数”就是最合适的。不过实际应用中,线程数量一般会设置为“CPU核数 + 1" ,这样的话,当线程因为偶尔的内存页失效或其他原因导致阻塞时,这个额外的线程可以顶上,从而保证CPU利用率。

♠ I/O密集型

对于I/O密集型的计算场景,比如前面的例子中,如果 CPU 计算和 I/O 操作的耗时是1:1,那么2个线程是最合适的。如果 CPU 计算和 I/O 操作的耗时是1:2,那多少个线程合适呢?是3个线程,如图所示:CPU在A、B、C三个线程之间切换,对于线程A,当CPU 从B、C线程切换回来时,线程A正好执行完I/O操作。这样 CPU 和 I/O 设备的利用率都达到了100%。
                 
通过上面这个例子,我们发现,对于I/O 密集型计算场景,最佳线程数是与程序中CPU计算和I/O操作的耗时比相关的。
可以总结一个公式:最佳线程数 = 1 + (I/O 耗时 / CPU耗时)

我们令 R = I/O 耗时 / CPU耗时,综合上图,可以理解成:当线程A执行IO操作时,另外 R 个线程正好执行完各自的CPU计算。这样CPU利用率就达到了100%。

对于多核CPU,等比扩大即可:最佳线程数 = CPU核数 * [ 1 + (I/O 耗时 / CPU耗时)]

有收获的话,点个赞吧~

【多线程】创建多少线程才是合适的相关推荐

  1. 高并发场景下创建多少线程才合适?一条公式帮你搞定!!

    来自:冰河技术 创建多少线程合适, 要看多线程具体的应用场景.一般来说,我们可以将程序分为:CPU密集型程序和I/O密集型程序, 而针对于CPU密集型程序和I/O密集型程序,其计算最佳线程数的方法是不 ...

  2. 多线程创建方式 线程池、Future和CompletableFuture

    大家好,我是烤鸭: 今天说一下 多线程的几种创建方式及使用. 1. Thread 和 Runnable 继承 Thread 类 和实现 Runnable 接口.     这种就不举例子了. 2.线程池 ...

  3. java多线程创建runnable_Java线程池和runnables创建runnables

    有很多方法可以做你想要的 . 您需要小心,不要最终创建太多线程 . 以下是一个示例,您可以使用ExecutorCompletionService提高效率,也可以使用Runnable . import ...

  4. burp爆破线程设置多少_你知道线程池创建多少线程比较合理吗?

    为什么会使用多线程 创建多少线程比较合适 结束语 <Java 2019 超神之路> <Dubbo 实现原理与源码解析 -- 精品合集> <Spring 实现原理与源码解析 ...

  5. java 线程池数量_java线程池及创建多少线程合适

    java线程池 1.以下是ThreadPoolExecutor参数完备构造方法: public ThreadPoolExecutor(int corePoolSize,int maximumPoolS ...

  6. Java多线程学习(二)---线程创建方式

    线程创建方式 摘要: 1. 通过继承Thread类来创建并启动多线程的方式 2. 通过实现Runnable接口来创建并启动线程的方式 3. 通过实现Callable接口来创建并启动线程的方式 4. 总 ...

  7. 【Java】多线程相关复习—— 线程的创建、名字、运行情况以及顺序控制(join方法) 【一】...

    一.创建线程的三种方式 · 继承Thread类 · 实现Runnable接口 · 实现Callable接口 二. 线程状态 · 线程名字 getName() · 线程活动情况 isAlive() · ...

  8. java线程的创建线程_多线程(Thread、线程创建、线程池)

    第1章 多线程 1.1 多线程介绍 学习多线程之前,我们先要了解几个关于多线程有关的概念. 进程:进程指正在运行的程序.确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序, ...

  9. VC多线程编程之线程创建与示例

    一.问题的提出 编写一个耗时的单线程程序: 新建一个基于对话框的应用程序SingleThread,在主对话框IDD_SINGLETHREAD_DIALOG添加一个按钮,ID为IDC_SLEEP_SIX ...

最新文章

  1. mysql50到例题_关于MySQL的经典例题50道 答案参考
  2. Memcached通用类(基于enyim.com Memcached Client)
  3. 压缩图片_Word快速压缩图片大小
  4. Curator实现分布式锁的基本原理-LockInternals.attemptLock
  5. 反射获取构造方法并运行的快速的方式
  6. win7 没有microsoft print to pdf_现在还能不能下载到正版WIN 7
  7. 在mac os10.13系统下 ,将py文件打包成可执行程序后, 里面的路径出现的问题
  8. 10W阅读,万人点赞,这套大数据平台建设方法论,到底有什么干货
  9. 关于extern C
  10. java装饰者模式讲解视频教程_java装饰者模式介绍(图文教程)
  11. java开发的主流_盘点2019年Java开发中7项主流、热门的IT技术!
  12. HTML不熟悉方法总结
  13. 韦东山嵌入式Linux学习——015 Nand Flash(2)-Nand Flash编程实现读地址信息
  14. 乐高ev3编程 c语言,乐高ev3编程软件下载-乐高EV3机器人编程软件lego mindstorms ev31.0 官方版 - 极光下载站...
  15. STM32F4 使用 JFlash 加密后无法再擦除了
  16. Eplan教学视频合集-百度网盘-收集于网络
  17. 永恒之蓝MS17-010漏洞复现
  18. noip2003 侦探推理 (字符串处理)
  19. Spring-@Bean
  20. 字典学习/稀疏表示学习笔记

热门文章

  1. Spring中使用JdbcTemplate和HibernateTemplate的数据库操作
  2. ASP.NET URL Rewrite. URL重写
  3. Python Type Hint类型注解
  4. python笔记01_高级特性和函数式编程
  5. 设计一个60T数据仓库及大数据分析平台,医院数字化该怎么做?
  6. java实现文件上传和文件查看、下载
  7. HTML限制输入个数,如何使用CSS(或jQuery,如果需要)限制输入HTML输入的字符数?
  8. 重新打包mysql数据库文件_服务器每天早上备份一次 MySQL 数据库并自动打包,同时删除 5 天前的备份文件...
  9. unity多人联机插件_Mirror ---Unity多人联机游戏API(一)
  10. Python 之详解深拷贝和浅拷贝