`

为什么要用多线程

阅读更多
以前我认为多线程的作用就是提升性能。实际上,多线程并不一定能提升性能(甚至还会降低性能);多线程也不只是为了提升性能。多线程主要有以下的应用场景:

1、避免阻塞(异步调用)

单个线程中的程序,是顺序执行的。如果前面的操作发生了阻塞,那么就会影响到后面的操作。这时候可以采用多线程,我感觉就等于是异步调用。这样的例子有很多:

ajax调用,就是浏览器会启一个新的线程,不阻塞当前页面的正常操作;

流程在某个环节调用web service,如果是同步调用,则需要等待web service调用结果,可以启动新线程来调用,不影响主流程;

android里,不要在ui thread里执行耗时操作,否则容易引发ANR;

创建工单时,需要级联往其他表中插入数据,可以将级联插入的动作放到新线程中,先返回工单创建的结果……

2、避免CPU空转

以http server为例,如果只用单线程响应HTTP请求,即处理完一条请求,再处理下一条请求的话,CPU会存在大量的闲置时间

因为处理一条请求,经常涉及到RPC、数据库访问、磁盘IO等操作,这些操作的速度比CPU慢很多,而在等待这些响应的时候,CPU却不能去处理新的请求,因此http server的性能就很差

所以很多web容器,都采用对每个请求创建新线程来响应的方式实现,这样在等待请求A的IO操作的等待时间里,就可以去继续处理请求B,对并发的响应性就好了很多

当然,这种设计方式并不是绝对的,现在像node.js、Nginx等新一代http server,采用了事件驱动的实现方式,用单线程来响应多个请求也是没问题的。甚至实现了更高的性能,因为多线程是一把双刃剑,在提升了响应性的同时,创建销毁线程都是需要开销的,另外CPU在线程之间切换,也会带来额外的开销。避免了这些额外开销,可能是node.js等http server性能优秀的原因之一吧

3、提升性能

在满足条件的前提下,多线程确实能提升性能

打一个比方,多线程就相当于,把要炒的菜放到了不同的锅里,然后用不同的炉来炒,当然速度会比较快。本来需要先炒西红柿,10分钟;再炒白菜10分钟;加起来就需要20分钟。用了多线程以后,分别放在2个锅里炒,10分钟就都炒好了

基本上,需要满足3个条件:

第1,任务具有并发性,也就是可以拆分成多个子任务。并不是什么任务都能拆分的,条件还比较苛刻

子任务之间不能有先后顺序的依赖,必须是允许并行的

比如
a = b + c
d = e + f

这个是可以并行的;
a = b + c
d = a + e

这个就无法并行了,第2步计算需要依赖第1步的计算结果,即使分成2个线程,也不会带来任何性能提升

另外,还不能有资源竞争。比如2个线程都需要写一个文件,第1个线程将文件锁定了,第2个线程只能等着,这样的2个子任务,也不具备并发性;执行sychronized代码,也是同样的情况

第2,只有在CPU是性能瓶颈的情况下,多线程才能实现提升性能的目的。比如一段程序,瓶颈在于IO操作,那么把这个程序拆分到2个线程中执行,也是无法提升性能的

第3,有点像废话,就是需要有多核CPU才行。否则的话,虽然拆分成了多个可并行的子任务,但是没有足够的CPU,还是只有一个CPU在多个线程中切换来切换去,不但达不到提升性能的效果,反而由于增加了额外的开销,而降低了性能。类似于虽然把菜放到了2个锅里,但是只有1个炉子一样

如果上述条件都满足,有一个经验公式可以计算性能提升的比例,叫阿姆达尔定律:

速度提升比例 = 1/[(1-P)+(P/N)],其中P是可并行任务的比例,N是CPU核心数量

假设CPU核心是无限的,则公式简化为1/(1-P)

假设P达到了80%(已经非常高了),那么速度提升比例也只能达到5倍而已
分享到:
评论

相关推荐

    权威.NET多线程详解(源码示例)

    综上,理解并熟练应用.NET多线程技术,能有效提升程序的并发性能,解决复杂的并发问题,为应用程序设计提供更多的可能性。在实践中,应结合业务逻辑和系统需求,合理选择同步和异步策略,以及线程管理方式,确保程序...

    多线程编程学习资料(适合中级读者)

    首先,"多线程编程之一——问题提出"部分,会引出为什么要使用多线程编程的问题。在单核CPU时代,多线程主要是为了提高程序响应性,避免长时间阻塞主线程导致用户界面冻结。随着多核CPU的普及,多线程成为充分利用...

    用VB6实现多线程

    在VB6(Visual Basic 6)环境中,多线程是一个重要的技术,它允许程序同时执行多个任务,提高程序的响应性和效率。VB6本身并不直接支持多线程,但可以通过调用Windows API来实现。本篇文章将深入探讨如何在VB6中实现...

    C#.NET多线程实例6个(包括多线程基本使用,多线程互斥等全部多线程使用实例),可直接运行

    本资源包含六个C#.NET多线程的实例,涵盖了多线程的基本使用到更高级的概念,如线程互斥。以下是这些实例可能涉及的关键知识点: 1. **线程创建**:C#中创建线程主要有两种方式,一是通过`System.Threading.Thread`...

    PB多线程实现

    PB12.5引入了对多线程的更好支持,它引入了一个名为“Worker Thread”的新概念。开发者可以创建一个工作线程对象,然后在这个对象上执行自定义的代码块。这使得在PB应用中实现多线程变得更加简单。在PB12.5中,还...

    多线程编程示例

    首先,我们需要理解什么是多线程。多线程是指在一个进程中同时执行多个独立的执行线程。在单核CPU系统中,操作系统通过时间片轮转的方式在不同线程之间切换,营造出并发执行的假象;而在多核或多处理器系统中,线程...

    易语言多线程传递多参数

    在编程领域,多线程是实现并发执行任务的重要机制,特别是在易语言中,它能有效提升程序的执行效率。易语言是一种中文编程语言,旨在降低编程门槛,让普通用户也能进行程序开发。本文将深入探讨易语言中的多线程以及...

    鱼刺多线程模块

    "鱼刺多线程模块"是一个专为提升程序运行效率而设计的开源组件,它主要聚焦于多线程技术的应用。在计算机科学中,多线程是并发执行多个任务或子任务的一种方法,使得程序能够更高效地利用系统资源,特别是在多核...

    易语言多线程许可证使用

    许可证管理在多线程环境下变得尤为重要,因为多个线程可能同时尝试访问或修改许可证信息。在易语言中,这可能需要使用同步机制,如锁、信号量或者事件对象,来确保许可证的正确读写。例如,当一个线程获取许可证后,...

    C#多线程互斥实例 多线程获取同一变量

    在编程领域,多线程是实现并发执行任务的重要机制,特别是在现代计算机系统中,多核处理器使得多线程成为提高程序性能的关键手段。C#语言提供了丰富的多线程支持,让我们能够编写出高效的多线程应用程序。在这个"多...

    C#多线程 C#多线程

    本文将深入探讨C#中的多线程概念、线程池的使用以及如何通过实例理解其工作原理。 首先,多线程在C#中是通过`System.Threading`命名空间中的类实现的,例如`Thread`和`ThreadPool`。`Thread`类代表一个独立的执行...

    多线程框架通用多线程源码.zip

    《深入理解易语言版多线程通用框架》 ...通过深入研究"多线程5.e"中的代码,开发者不仅可以学习到多线程的基本原理,还能了解到如何在易语言中实现高效的多线程编程,为复杂系统的开发打下坚实基础。

    鱼刺多线程注册源码例子(鱼刺多线程稳定框架)

    在这个例子中,"鱼刺框架"可能是一个专门为多线程编程设计的开源或商业库,它提供了一系列工具和接口,帮助开发者更好地管理和协调多个并发执行的线程。 首先,我们需要理解多线程的基本概念。在计算机科学中,线程...

    C#泛型参数多线程与复杂参数多线程2

    最近用多线程用的比较多自己走了一些弯路,分享出来希望大家少走弯路,C#中的多线程有两个重载,一个是不带参数的,一个是带参数的,但是即便是带参数的多线程也不支持泛型,这使得使用泛型参数多线程的时候很不方便...

    多线程的运用e语言多线程 e多线程

    总之,E语言的多线程技术为开发者提供了高效、灵活的并发编程能力,但同时也需要注意线程安全和资源管理,以确保程序的稳定性和性能。通过合理利用多线程,可以在各种复杂场景下实现高效的代码执行。

    易语言源码多线程类源码.rar

    综上所述,这个压缩包中的内容是关于易语言下实现多线程程序的实例,包括源代码和使用说明,对于想要学习易语言多线程编程的开发者来说是一份宝贵的资料。通过研究这些内容,可以深入理解易语言的线程机制,并掌握...

    .Net 多线程详解

    • 什么是用双锁实现Singleton,为什么要这样做,为什么有人说双锁检验是不安全的 • 互斥对象(Mutex)、事件(Event)对象与lock语句的比较 什么时候需要锁定 • 只有共享资源才需要锁定 • 把锁定交给数据库 •...

    .NET多线程实例

    .NET框架的多线程技术是开发高性能应用程序的关键组成部分,特别是在处理并发操作、并行计算以及UI更新时。在.NET 2.0版本中,多线程功能已经得到了充分的优化和增强,允许开发者构建出更加高效的应用程序。下面将...

    C# 多线程实例多线程实例多线程实例

    在编程领域,多线程是实现并发执行任务的关键技术,特别是在C#这样的语言中,它提供了丰富的多线程支持。本文将深入探讨C#中的多线程实例,以帮助开发者理解如何有效地利用多核处理器资源,提高程序的执行效率。 多...

    单线程与多线程的区别

    在Java或C#这样的多线程环境下,可以使用如`Thread`类或`ThreadPool`来创建和管理线程,也可以利用`Runnable`接口或`ThreadStart`委托定义线程的执行逻辑。线程间的通信可以通过`Monitor`、`Mutex`、`Semaphore`等...

Global site tag (gtag.js) - Google Analytics