多线程发展史

本文详细讲述了多线程技术的起源,从早期的纸带机、单道批处理系统,到多道批处理系统和多线程的出现,以及多线程如何通过时间片和多核CPU提高CPU利用效率。文章还比较了线程与进程的区别,讨论了线程的生命周期和创建方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程这个词,我们都很熟悉,写代码的时候也都用过多线程,可是,你知道多线程是怎么被我们聪明人类发明而来的吗?了解了多线程的发展历程,和每个阶段核面临要解决的问题,你就自然而然的理解了为什么现在多线程是这样设计的,下次面试也有了吹牛的底气。知其然,更要知其所以然。

多线程的发展历程

1)纸带机

在最开始的时候,计算机是通过穿孔打卡实现的,将程序预先写到纸上,穿孔成卡片,将卡片上的程序输入到计算机上,计算机运行完当前的任务之后,把结果从打印机上进行输出,然后计算机等待下一个程序的输入。
在这里插入图片描述这种处理会造成计算机极大空闲。比如程序输入时,计算机是处在等待输入的空闲状态的。
在这里插入图片描述

2)单道批处理系统

为了减少机器的空闲等待时间,后续出现了单道批处理系统,系统对作业处理是成批进行的。需要把一批作业输入到磁带上, 使得程序能一个接一个的连续处理,但是在内存中始终值保持一道作业。由于内存中只有一道程序,在程序运行中涉及IO操作较多时,CPU只能阻塞直到该IO完成,因此造成CPU资源浪费。
在这里插入图片描述

3)多道批处理系统

为了更高的利用CPU资源,便出现了多道程序的设计。系统中存在多个程序,当一个进程需要等待IO操作完成时,CPU可以切换到另一个进程。任务执行的这一小段时间叫做时间片,由于CPU在不同的进程间进行时间片切换,CPU的执行效率非常高,时间短,所以可以让操作系统从宏观层面看,是多应用并行运行。在CPU微观层面上,对于单核CPU来说,一个时刻只有一个进程在执行,底层就是通过CPU时间片不断切换来实现的。

在这里插入图片描述

4)多线程

为了对CPU进一步的压榨,将进程再进行切分更小的颗粒,这些进程的小颗粒可以并行执行,共享进程的资源,如同上面介绍的多道批处理系统一样的原理,从而提高了进程整体的执行速度。这些小颗粒就是线程,这就像学习物质组成一样,分子,再到原子,再到原子核、电子等类似的原理。后续由于硬件的发展,随着多核CPU等计算机的出现,多核CPU利用多线程实现了真正意义上的并行执行。多线程可以提高程序的并发和响应,减少切换开销,并且可以方便地共享数据。

5)纤程(协程)

随着技术的发展现在出现了纤程,纤程是用户管理的线程,是一种更轻量级的线程。线程属于操作系统管理。每一个线程创建都需要向操作系统申请创建,与操作系统交互,这样每启一个线程的代价都很高。一个线程可以拥有多个纤程。纤程目前使用的还不是很广,大多数还是使用的线程。

线程VS进程

通过上述介绍,我们知道,计算机最开始都是围绕着进程进行优化,那为什么有了进程,后面又有了线程呢?

进程是一个“执行中的程序”,例如我们的淘宝app就是一个进程,进程可以看作一个独立的应用。它是系统进行资源分配的基本单位。创建进程需要通过系统调用来分配内存空间、加载程序代码、设置进程环境等。进程的管理也需要通过系统调用来实现,比如进程的调度、进程的终止、进程的通信等。进程独占内存空间,保存各自的运行状态,相互间不打扰。进程切换时,涉及到当前进程的CPU环境的保存和被调度运行进程的CPU环境的设置。

线程是进程的一个实体,一个进程拥有多个线程,例如淘宝的订单页面,可能包含获取订单商品详情的线程、获取订单的线程等,两个线程同时执行,当然要比一个线程线性执行要快。一个进程的线程之间共享地址空间和其它资源,所以通信和同步等操作线程比进程更加容易。线程是CPU运行的基本单位,CPU调度的基本单位。线程切换仅需要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。多核CPU利用多线程,实现了真正意义上的并行执行。

一个进程,会存在多个同时执行的任务,如果一个任务被阻塞,将会引起不依赖该任务的任务也被阻塞,通过对不同任务创建不同的线程去单独执行,可以提升程序的运行速度,提高CPU的利用效率。线程可以认为是轻量级的进程,线程的创建、销毁比进程更快。

既然线程有这么多好处,那是不是线程越多效率越高呢?

当然不是,多线程,意味着cpu要进行频繁的上下文切换,切换也是需要消耗资源的,(上下文切换:将原来执行的线程数据保存起来,将将要执行的线程数据加载进来执行)。因此如果线程太多,时间都耗费在了上下文切换上了。

线程和进程都可以进行相互切换的,那他们之间在切换时,通讯有什么区别呢?

进程依赖IPC资源,例如:管道、套接字等。线程间通讯依靠JVM提供的API,例如wait()、notify()、notifyAll()等方法,线程间还可以通过共享的主内存来进行值的传递,因此线程之间的通信通常比进程之间的通信更快,更易于实现。

说了这么多,总之进程和线程的主要区别在于它们的内存空间和资源共享方式、创建和管理的系统调用数量、以及它们的通信方式。进程是独立的,有自己的内存空间和资源,而线程则共享它们所在的进程的内存和资源。进程需要更多的系统调用进行创建和管理,而线程是在进程内部创建的,只需要较少系统调用。进程需要使用IPC资源进行通信,而线程可以直接通信。

说了这么多线程内部实现机制,那我们怎么在代码中启动一个线程呢?线程的生命周期是什么样的呢?我们下一期详细介绍。

碎碎念

我输出的文章都是我多年面试大厂总结的经验,将各系列面试高频知识点抽出来进行全面解析,还有一些个人感悟等等。如果恰好对你有用处,**【点赞、关注、在看】**是我创作的最大动力!!!

我这里有份非常全的面试题,长达20万字,算是 Java 一整套技术栈都写了,包括 Java 基础,虚拟机,消息队列,框架等等。当然,还有通用基础知识,例如计算机网络,操作系统,Mysql,Redis 也都整理了,给大家看一下目录。

在这里插入图片描述

如何获取这份资料

关注公众号「话猫」,回复「1024」即可获取下载链接哦,以下是公众号

微信公众号

作者简洁

2018年非科班选手,2020花费两年时间从小厂跳入美团搬砖,2023年来到了职业的下一站~快手,这里有我5年职场故事与未来憧憬,欢迎围观一枚女程序猿的故事~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值