Java 异步编程——为什么要使用多线程,以及在什么情况下使用多线程?

前言

单线程就是一个工人在搬砖,多线程就是多个工人在搬砖;在相同数量的砖要搬的情况下,多个工人搬砖肯定比一个人搬的快。

那多个工人做事一定比一个工人做事快吗?那不一定,不过大多数情况下是的。多线程只是可以同时接收多个任务,但不一定马上去执行任务。这里要看有多少资源(单核 or 多核)和做什么任务(计算密集型任务 or IO密集型任务)。基于这两个条件进行笛卡尔积形成的场景来分析单线程和多线程的工作效率。

单核:单核处理器指的是只有一个物理核心的处理器。物理核心是处理器中的实际计算单元,能够执行指令和处理数据。在单核处理器中,只能同时执行一个线程或进程。即使使用多线程编程,也只能通过时间片轮转的方式在不同线程之间进行切换,每个线程在某个时间片内独占处理器的执行时间。

多核:多核处理器指的是具有多个物理核心的处理器。多核处理器将多个物理核心集成到一个芯片上,每个核心都是一个独立的计算单元,能够并行执行指令和处理数据。每个核心可以独立地执行一个线程或进程,因此多核处理器可以同时执行多个线程或进程,提供更高的并行处理能力。

计算密集型任务:计算密集型任务是指那些主要依赖 CPU 运算能力的任务。通常涉及大量的数值计算、复杂的算法或模型运算,而对于 I/O 操作的需求相对较低,受限于 CPU 的运算速度。
IO密集型任务:I/O 密集型任务是指那些主要依赖于输入/输出操作的任务。这些任务通常需要频繁地进行文件读写、网络通信、数据库访问等 I/O 操作,而对于 CPU 的计算能力需求相对较低。

单核 + 计算密集型任务:

在单核情况下,只有一个物理核心处理器,多线程和单线程最终都落在一个核心处理器(CPU)去处理任务,此时的多线程只是分时段的获取同一个CPU处理任务。就好比工人使用一个计算器来记账,最终都依靠计算器计算加减乘除来获得结果。

在处理计算密集型任务的时候,主要依赖CPU不停的运算来处理任务,这个时候无论是多线程还是单线程,接收单个或多个计算密集型任务,处理效率都没太大差距,因为只有一个CPU在不停地进行运算处理任务,接收的多个任务也只能一个个依次处理。就好比多个工人都在做记账任务,而计算器只有一个,需要等一个工人使用计算完后才能交给下一个工人记账,这个时候一个工人记多笔账还是多个工人分别记,都没太大差别,甚至还差一点,工人之间需要交换计算器会产生耗时,这就是多线程之间的切换开销。

单核+计算密集型任务场景时,使用单线程处理就可以了。

单核 + IO密集型任务:

在处理IO密集型任务的时候,虽然多线程和单线程最终都落在一个核心处理器(CPU)去处理任务,但在处理一个任务的整个过程中,CPU并不需要一直参与运算,此时多线程就可以充分利用CPU。对于单线程,在处理一个任务的整个过程中,只有需要运算的时候CPU才参与运算,其它时候CPU就在空转,一直到线程处理完;对于多线程,一个线程处理任务过程中,在需要运算时使用CPU运算,其它时候就不占用(异步执行IO操作),让其它需要进行运算的线程去占用运算,充分利用CPU让其不停的运算处理。

就好比工人用计算器计算登记货车运来的货物(计算器好比CPU,货车运货物好比IO流),一个工人在等待运砖块的货车,运砖货车一到,工人便拿起计算器累加计算已到的总砖块数量,计算登记好后等待下一辆运转货车到来,计算器也就放在一旁了,而每个工人职责分明,不会去登记其它货物,造成计算器资源浪费。如果同时有多个工人进行登记,一个工人计算登记好运砖货物便释放计算器并等待下一辆运转货车到来;在第一个工人等待过程中,下一个工人可以使用计算器计算登记运沙货物,登记好后释放计算器并等待下一辆运沙货车到来;一直释放、占用循环下去,充分利用计算器资源。

使用多线程能够充分利用CPU,看起来像多个任务同时并行接收与执行,但相对于CPU来说任务还是一个一个依次串行处理,并没有并行执行,只是CPU资源没有浪费,得到充分利用,效率便上来了。

单核+IO密集型任务场景时,使用异步IO操作时可以考虑使用多线程处理能提高处理效率,在进行异步IO操作时,线程可以释放CPU;使用同步IO操作时,线程会被阻塞,不会释放CPU,即使启动多个线程执行,多个线程也只是同时接收任务,最终任务还是被串行执行,所以使用多线程相比于单线程处理效率并没有提高,可能还会效率还低一点。

多核 + 计算密集型任务:

在多核情况下,有多个物理核心处理器,多个线程可以分别获取不同的核心处理器(CPU)同时处理任务。就好比工人使用计算器来记账,可以为每个工人都分配一个计算器,多个工人同时使用计算器计算加减乘除来获得结果。

在处理计算密集型任务的时候,使用多个线程可以同时接收多个计算密集型任务并进行运算处理,多个任务并行运算处理,提高整体的执行效率;而如果只使用单线程来处理,任务只能串行处理,一个线程只能使用一个CPU,其它CPU就处于空闲状态。就好比多个工人都在做记账任务,每个工人都配备一个计算器,这个时候每个工人可以并行计算记账,而无需等待。

多核 + 计算密集型任务场景时,使用多线程处理就可以极大提升任务处理效率。

多核 + IO密集型任务:

在处理IO密集型任务的时候,虽然多线程可以分别落在不同的核心处理器(CPU)去处理任务,不管是同步IO还是异步IO操作,多线程下都可以并行执行多个任务,相比于单线程处理效率得到极大提升。对于同步IO和异步IO操作,异步IO操作下可以使更多线程抢占CPU执行,更充分的利用CPU;同步IO操作会浪费大量的CPU资源。

同样使用工人用计算器计算登记货车运来的货物(计算器好比CPU,货车运货物好比IO流)的例子。对于同步IO,就好比工人使用完计算器后不给下一个工人使用,一直占有知道所有货物运完计算登记完为止。那么一个工人使用一个计算器只登记自己负责的货物线路,多个工人使用多个计算器可以同时并行登记各自负责的货物线路,任务处理速度是上来了,但浪费了更多的资源。对于异步IO,就好比工人使用完计算器后就释放出来不占用,让下一个工人使用。在指定数量的计算器下,就可以有指定数量的工人同时并行计算登记各自的货物线路,在使用计算器计算完后,释放计算器,在等待下一辆货车运货到来之前,就可以有多个计算器释放出来让其它多个工人继续使用登记,宏观上看,在指定数量的计算器下,有更多的工人同时计算登记,这样不仅任务处理速度是上来了,而且计算器也能够得到充分使用。

多核 + IO密集型任务场景时,使用多线程处理就可以极大提升任务处理速度。


异步 I/O 和同步 I/O 是两种不同的 I/O 操作模式,它们在执行过程和效率上有着明显的差异。

同步 I/O 操作:

  • 同步 I/O 操作会阻塞当前线程,直到 I/O 操作完成。
  • 在 I/O操作执行期间,当前线程无法处理其他任务,系统的并发能力受限。
  • 编程模型相对简单,代码结构清晰。
  • 适用于 CPU 密集型任务或 I/O操作时间较短的场景。

异步 I/O 操作:

  • 异步 I/O 操作不会阻塞当前线程,而是继续执行其他任务。
  • I/O 操作完成时,通过回调函数或事件通知调用者。
  • 可以通过多线程同时执行多个异步 I/O 操作,充分利用 CPU 资源,提高 I/O 吞吐量。
  • 适用于 I/O 密集型任务,如网络通信、文件I/O 等,可以提高系统的并发能力和响应性。
  • 但是实现异步 I/O 操作需要更复杂的编程模型,增加了代码的复杂度。

在单核 CPU 情况下,I/O 密集型任务使用同步 I/O 操作时,单线程和多线程的效率对比如下:

单线程同步 I/O 操作:

  • 在单核 CPU 上,当执行同步 I/O 操作时,当前线程会被阻塞,无法执行其他任务。
  • 整个系统只能顺序地执行 I/O 操作,效率较低。
  • 当 I/O 操作时间较长时,系统的响应性会大大降低。

多线程同步 I/O 操作:

  • 在单核 CPU 上,即使启动多个线程执行同步 I/O 操作,也只能被串行执行。
  • 每个线程在执行 I/O 操作时仍然会被阻塞,无法处理其他任务。
  • 线程上下文切换也会带来一定的性能开销。
  • 因此,多线程并不能提高 I/O 密集型任务在单核 CPU上的效率。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/12999.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java并发编程——线程安全

在Java并发编程中,线程安全是一个非常重要的概念。当多个线程同时访问共享数据时,如果没有采取适当的同步措施,就可能会导致数据不一致或其他不可预期的行为,这就是线程不安全的情况。 为了保证线程安全,Java提供了一…

Google Ads谷歌广告账户被封停怎么办?

跨境出海业务少不了需要做Google Ads推广业务;其中让投手们闻风丧胆的消息就是帐户被暂停。当 Google 检测到任何违反其政策且可能损害用户在线体验的行为时,就会发生这种情况。那么如何在做广告推广的同时,保证账号不被封禁呢?看…

【微服务最全详解】

文章目录 微服务微服务的介绍微服务服务架构演变 微服务网关微服务的负载均衡微服务的容灾机制服务崩溃服务容灾机制微服务熔断机制微服务限流Sentinel怎么实现限流微服务限流算法1.令牌桶算法2.漏斗桶算法 服务监控日志收集 微服务 微服务的介绍 微服务是一种软件架构风格&a…

大模型日报2024-05-15

大模型日报 2024-05-15 大模型资讯 OpenAI推出全新AI模型GPT-4o,具备文本、图像和音频处理能力 摘要: OpenAI公司继ChatGPT后,最新推出了名为GPT-4o的AI模型。这一模型不仅能够理解和生成文本,还新增了图像和音频的解释及生成功能。GPT-4o作为…

中国开源 AI 大模型之光-InternLM2

今天给大家带来 AI 大模型领域的国产之光 - InternLM2,在10B量级开源大模型领域取得了全球 Top 3 的成绩,仅次于 Meta 发布的 Llama-3,在国内则是第一名的存在! 简介 InternLM2是由上海人工智能实验室和商汤科技联合研发的一款大型…

最大子序列的分数

题目链接 最大子序列的分数 题目描述 注意点 n nums1.length nums2.length从nums1和nums2中选一个长度为k的子序列对应的下标对nums1中下标对应元素求和&#xff0c;乘以nums2中下标对应元素的最小值得到子序列的分数0 < nums1[i], nums2[j] < 1000001 < k < …

Leecode热题100---560:和为k的子数组个数

题目&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 C&#xff1a; #include<iostream> #include<vector> using namespace std; class Solution { public:…

AI作画算法详解:原理、应用与未来发展

随着人工智能技术的不断发展&#xff0c;AI作画逐渐成为了一个热门话题。AI作画&#xff0c;即利用人工智能算法生成绘画作品&#xff0c;不仅仅是技术的展示&#xff0c;更是艺术与科技结合的创新体现。本文将深入探讨AI作画的核心算法原理&#xff0c;并通过实例帮助读者更好…

多步预测系列 | LSTM、CNN、Transformer、TCN、串行、并行模型集合

● 环境框架&#xff1a;python 3.9 pytorch 1.8 及其以上版本均可运行 ● 使用对象&#xff1a;论文需求、毕业设计需求者 ● 代码保证&#xff1a;代码注释详细、即拿即可跑通。 往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分…

数据结构篇3—《龙门客“栈”》

文章目录 &#x1f6a9;前言1、栈的概念2、栈的实现框架3、栈的代码实现3.1、栈的初始化和销毁3.2、入栈\出栈\返回栈顶元素\元素个数\判空3.3、栈定义注意事项 4、栈的应用实例——《括号匹配问题》 &#x1f6a9;前言 前面记录了关于顺序表和链表的数据结构&#xff0c;这一篇…

【CF1965A】Everything Nim

题目链接 前置trick&#xff1a; 使用vector去重&#xff1a; vector<int> a(n);for(int i0;i<n;i) cin>>a[i];sort(a.begin(),a.end());a.erase(unique(a.begin(),a.end()),a.end());na.size();题意&#xff1a; 有 n n n堆石子&#xff0c;第 i i i堆有 a i a…

【企业宣传片】拍摄思维提升,专业影视质感核心揭密,一课搞定

课程下载&#xff1a;【企业宣传片】拍摄-课程网盘链接提取码下载.txt资源-CSDN文库 更多资源下载&#xff1a;关注我。 课程介绍 大量案例分析宣传片拍摄的痛点要点 根据案例告诉你解决方案&#xff0c;讲透概念 改变你对企业宣传片的思维层级与认知 归纳总结对比不同案…

C++语法|类直接包含与自身类型相同的成员变量?

在C中&#xff0c;一个类不能直接包含与自身类型相同的成员变量。这是因为类的大小需要在编译时确定&#xff0c;而一个包含自身类型的成员变量会导致递归定义&#xff0c;从而无法确定类的大小。 文章目录 示例代码&#xff08;非法定义&#xff09;解决办法1.使用指针2.使用智…

k8s 二进制安装 优化架构之 部署负载均衡,加入master02

目录 一 实验环境 二 部署 CoreDNS 1&#xff0c;所有node加载coredns.tar 镜像 2&#xff0c;在 master01 节点部署 CoreDNS 3&#xff0c; DNS 解析测试 4&#xff0c; 报错分析 5&#xff0c;重新 DNS 解析测试 三 master02 节点部署 1&#xff0…

AI学习指南数学工具篇-PCA的应用场景

AI学习指南数学工具篇-PCA的应用场景 在人工智能领域&#xff0c;数据处理是非常重要的一环。对于大量高维数据&#xff0c;我们往往需要进行数据降维来减少计算复杂度&#xff0c;同时利用可视化工具对数据进行分析和理解。主成分分析&#xff08;Principal Component Analys…

C++ 利用标准库多字节转宽字节字符

在 C/C 之中&#xff0c;通常建议使用&#xff1a;mbstowcs &#xff08;C语言函数库&#xff09;来实现多字节字符转宽字节字符&#xff0c;这是因为如果使用。 std::wstring_convert<std::codecvt_utf8<wchar_t>> 模板来实现&#xff0c;它可能导致程序崩溃的风险…

【利用数组处理批量数据-谭浩强配套】(适合专升本、考研)

无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 无偿分享学习资料&#xff0c;需要的小伙伴评论区或私信dd。。。 完整资料如下&#xff1a;纯干货、纯干货、纯干货&#xff01;&#xff01;…

点云成图原理

点成图&#xff08;Point Cloud&#xff09;是指由一组离散的点构成的图形&#xff0c;它们在空间中没有任何连接关系。点成图通常是由激光雷达、相机或其他传感器获取的三维数据&#xff0c;用于表示现实世界中的物体或场景。 三角成图&#xff08;Triangulation&#xff09;…

element ui Tree树形控件

lazy 是否懒加载子节点&#xff0c;需与 load 方法结合使用 boolean 默认为falseload 加载子树数据的方法&#xff0c;仅当 lazy 属性为true 时生效 function(node, resolve)使用懒加载load不需要再使用data&#xff0c;利用resolve返回值即可注意&#xff1a;第一层的数据要写…

PMR-440N7Q韩国施耐德三和相序继电器EOCR-PMR

韩国施耐德三和EOCR继电器PMR-440N7Q PMR-440-N 直流电动机保护器:DCL、DOCR-S/H 欠电流继电器:EUCR-3C 交流电压继电器:EOVR、EVR-PD、EVR-FD、EUVR 韩国三和EOCR电动机保护器:EOCR-SS、EOCR-SS1/SS2、EOCR-AR、EOCR-ST、EOCR-SP、EOCR-SP1/SP2、EOCR-SE、EOCR-SE2/SE PMR-44…