前言
实事求是地讲,对于绝大多数研发人员,平时用到多线程的场景并不多。但多线程在我们的日常开发中却无处不在,只不过很多时候,框架已经帮你实现了。比如 web 开发,容器已经帮你实现了多线程;再比如大数据开发,框架也已帮你实现了多线程,甚至分布式计算。那促使你学习多线程的原因是什么呢想很大可能你是为了面试打基础、做准备。没错,这真的很现实!
面试官考查多线程的原因
1. 考察你的工作技术深度。
多线程虽然很少用到。但是如果你做底层开发,或者负责基础设施(例如消息队列)研发,肯定会用到多线程。通过面试多线程,可以考察你的工作在技术方面的深度。
2 考察你的学习、理解能力。
面试大概率会考多线程问题,这已经是公开的秘密了。这其实是一个开卷考试,对所有候选人是公平的。比拼的是候选人的学习能力、理解
能力、做事的态度。你可以没用过,但你要有快速掌握的能力,和稳扎稳打的学习态度。
我认为第二点是主要原因。求职者都知道面试官会考查多线程,但为什么还是有的人答非所问,有的人却对答如流,有的人甚至可以深入底层原理无外乎两个原因:
- 对面试的准备和态度。明知道要考察多线程,候选人却不认真准备,这种态度带到工作中是何其的可怕/li>
- 学习的能力。短时间内掌握平时不常用到的多线程并不容易。彻底理解多线程,还需要 JVM 的知识。这除了自身的学习能力外,如果配合一本好的教材、几篇好的博客,能够大大加快你的学习速度、提升你的学习深度。
软件世界即现实世界
虽然可能绝大多数学习者是抱着提升自身实力,为面试做准备的初衷来学习多线程。但我想告诉大家,多线程真的很强大,有很多使用场景,能帮你解决很多问题。在学习完多线程后,你手中便多了一样武器,你解决问题的思路也更为宽广。在你以后漫漫的编程生涯中,从此多了一种选择。所以学习多线程,绝对不是仅仅为了面试。
其实多线程并不复杂,其实和现实世界中多人协作是一样的。编程初学者,会觉得软件是无形的,看不见、摸不到,只有冰冷冷的逻辑,学习起来晦涩难懂。其实从面向对象出现开始,软件已经成为现实世界的对等映射。这不光体现在语言本身,其实在软件领域无处不在,例如:
1. 设计模式
23 种经典设计模式,没有哪一种不是从现实世界得来的灵感。如果你看过设计模式的文章,你一定对设计模式中生动有趣的例子所吸引。
2. 软件设计
绝大多数软件的设计,都参考了工业设计或者参考了生活中解决问题的方式,汲取其中的设计思想。其实不管软件还是硬件或者生活中遇到的难题,在解决问题的思路上是一致的。无形的软件设计,可以借助有形世界里的案例来帮助你思考。例如 kafka 的源代码,其中 producer 的设计思想和快递公司发快递的过程很类似。还有 Java NIO,也是类似的原理。可以说软件设计的思想都发源于现实世界。
3. 软件架构
我做个类比,软件架构可以看作现实世界工厂里的机器设计和布置。我们需要考虑很多,比如需要哪些机器,不同机器如何配比、不同工序之间如何衔接、机器出问题如何应对、机器操作日志如何记录、安全如何保障。工厂里遇到的问题在软件架构上也都会遇到。
以上举例,足以说明软件和现实世界之间的相似程度。软件其实就是现实世界的映射。我们在学习软件的过程中,要善于找到生活中常见的例子类比,这样理解起来就没有困难了,而且便于记忆。
进程与线程
进程
- 程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU,数据加载至内存。在指令运行过程中还需要用到磁盘、 络等设备。进程就是用来加载指令、管理内存、管理 IO 的
- 当一个程序被运行,从磁盘加载这个程序的代码至内存,这时就开启了一个进程。
- 进程就可以视为程序的一个实例。大部分程序可以同时运行多个实例进程(例如记事本、画图、浏览器等),也有的程序只能启动一个实例进程(例如 易云音乐、360 安全卫士等)
线程
- 一个进程之内可以分为一到多个线程。
- 一个线程就是一个指令流,将指令流中的一条条指令以一定的顺序交给 CPU 执行
- Java 中,线程作为最小调度单位,进程作为资源分配的最小单位。 在 windows 中进程是不活动的,只是作为线程的容器
二者对比
- 进程基本上相互独立的,而线程存在于进程内,是进程的一个子集
- 进程拥有共享的资源,如内存空间等,供其内部的线程共享
- 进程间通信较为复杂
- 同一台计算机的进程通信称为 IPC(Inter-process communication)
- 不同计算机之间的进程通信,需要通过 络,并遵守共同的协议,例如 HTTP
- 线程通信相对简单,因为它们共享进程内的内存,一个例子是多个线程可以访问同一个共享变量
- 线程更轻量,线程上下文切换成本一般上要比进程上下文切换低
并行与并发
单核 cpu 下,线程实际还是 串行执行 的。操作系统中有一个组件叫做任务调度器,将 cpu 的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于 cpu 在线程间(时间片很短)的切换非常快,人类感觉是 同时运行的 。总结为一句话就是: 微观串行,宏观并行 ,一般会将这种 线程轮流使用 CPU 的做法称为并发, concurrent
CPU | 时间片1 | 时间片2 | 时间片3 | 时间片4 |
---|---|---|---|---|
core | 线程1 | 线程2 | 线程3 | 线程4 |
多核 cpu下,每个 核(core) 都可以调度运行线程,这时候线程可以是并行的。
CPU | 时间片1 | 时间片2 | 时间片3 | 时间片4 |
---|---|---|---|---|
Core1 | 线程1 | 线程1 | 线程3 | 线程3 |
Core2 | 线程2 | 线程4 | 线程2 | 线程4 |
并发
并发(concurrent)是同一时间应对(dealing with)多件事情的能力。
例如:家庭主妇做饭、打扫卫生、给孩子喂奶,她一个人轮流交替做这多件事,这时就是并发
并行
并行(parallel)是同一时间动手做(doing)多件事情的能力
例如:雇了3个保姆,一个专做饭、一个专打扫卫生、一个专喂奶,互不干扰,这时是并行
https://www.imooc.com/read/49/article/937
https://www.bilibili.com/video/BV16J411h7Rd=1
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树Java异步任务线程与进程91719 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!