线程学习(1)-进程与线程

工作四年了,线程这个东西学的还是似是而非的,在工作中也不敢使用。所以趁着现在离职,好好学习一次,为以后的使用做准备。

学习课程链接: ​​​​​​黑马程序员全面深入学习Java并发编程,JUC并发编程全套教程_哔哩哔哩_bilibili

开始正题吧。

线程与进程的区别

进程

程序是由指令以及数据两部分组成,为了保证指令可以被运行,数据可以读写,需要将指令加载至CPU(可参考javap指令)中,数据加载至内存中(JVM内存模型结构)。其中可能涉及到诸多IO操作,利用到磁盘(数据库硬盘数据加载至buffer Pool内存中),网络(Socket远程传输数据)等各类数据。进程的作用就是用来加载指令,管理内存,管理IO的。

当一个程序被运行,从硬盘中将代码编译并加载至内存,这个进程便已经启动。

进程可以视为一个实例。有的进程可以启动多次,比如记事本,画图等。有的只能启动一次,比如网易云音乐,360卫士等。

线程

线程是进程的子集,一个进程可以包含多个线程。

线程底层就是一个指令流,将指令流中的一条条指令交给CPU来进行统一调度。

在java中,线程是一个最小调度单位,进程作为分配资源的最小单元。

二者区别

进程基本上相互独立的,而线程存在于进程内,是进程的一个子集
进程拥有共享的资源,如内存空间等,供其内部的线程共享
进程间通信较为复杂
同一台计算机的进程通信称为 IPC(Inter-process communication)
不同计算机之间的进程通信,需要通过网络,并遵守共同的协议(网络通信),例如 HTTP
线程通信相对简单,因为它们共享进程内的内存(内存通信),一个例子是多个线程可以访问同一个共享变量
线程更轻量,线程上下文切换成本一般上要比进程上下文切换低

并行和并发

单核CPU下,线程底层采用的是串行执行的。操作系统底层存在组件,任务调度器,将CPU的时间片分给不同的程序来使用,因为CPU中的时间片切换速度较快,所以感觉是同时运行的。微观运行,宏观串行。

当多个线程在单核CPU情况下执行任务时,即在某一时间段对多个任务来进行执行时,会将这种线程轮流使用 CPU 的做法称为并发。

多核 cpu下,每个 核(core) 都可以调度运行线程,这时候线程可以是并行的。

应用
 

以调用方角度来讲,如果
需要等待结果返回,才能继续运行就是同步
不需要等待结果返回,就能继续运行就是异步
1) 设计
多线程可以让方法执行变为异步的(即不要巴巴干等着)比如说读取磁盘文件时,假设读取操作花费了 5 秒钟,如果没有线程调度机制,这 5 秒 cpu 什么都做不了,其它代码都得暂停...
2) 结论
比如在项目中,视频文件需要转换格式等操作比较费时,这时开一个新线程处理视频转换,避免阻塞主线程tomcat 的异步 servlet 也是类似的目的,让用户线程处理耗时较长的操作,避免阻塞 tomcat 的工作线程
ui 程序中,开线程进行其他操作,避免阻塞 ui 线程

* 应用之提高效率(案例1)
充分利用多核 cpu 的优势,提高运行效率。想象下面的场景,执行 3 个计算,最后将计算结果汇总。

计算1划分10ms,计算 2花费11ms,计算3花费9ms,汇总需要耗费1ms。
如果是串行执行,那么总共花费的时间是 10 + 11 + 9 + 1 = 31ms
但如果是四核 cpu,各个核心分别使用线程 1 执行计算 1,线程 2 执行计算 2,线程 3 执行计算 3,那么 3 个线程是并行的,花费时间只取决于最长的那个线程运行的时间,即 11ms 最后加上汇总时间只会花费 12ms
注意
需要在多核 cpu 才能提高效率,单核仍然时是轮流执行
1) 设计
>>>>> 代码见【应用之效率-案例1】<<<<<
2) 结论
1. 单核 cpu 下,多线程不能实际提高程序运行效率,只是为了能够在不同的任务之间切换,不同线程轮流使用cpu ,不至于一个线程总占用 cpu,别的线程没法干活
2. 多核 cpu 可以并行跑多个线程,但能否提高程序运行效率还是要分情况的。有些任务,经过精心设计,将任务拆分,并行执行,当然可以提高程序的运行效率。但不是所有计算任
务都能拆分(参考后文的【阿姆达尔定律】)
也不是所有任务都需要拆分,任务的目的如果不同,谈拆分和效率没啥意义
3. IO 操作不占用 cpu,只是我们一般拷贝文件使用的是【阻塞 IO】,这时相当于线程虽然不用 cpu,但需要一直等待 IO 结束,没能充分利用线程。所以才有后面的【非阻塞 IO】和【异步 IO】优化。

总结
 

上面的都是粘的课件上面的东西,总结一下吧

多线程提升效率提升性能提升,其实提升的是资源利用率,而不是提升的资源执行效率。

因为在单核CPU场景下,在利用多线程执行任务时,任务依旧是串行执行的,而且因为多线程 上下文切换时会存在一定的开销,性能会降低。从这里可以看出来,资源执行效率并没有提升。

而在多核CPU场景下,利用多线程执行任务时,假设我现在有两个核,此时我要执行了两个任务,那么这两个任务会分别交给CPU的两个核来进行执行。此时,这个任务的执行速率,取决于这两个任务中执行时间较长的那个任务。也就是说,性能的提升,是依赖于并行执行来提升的。

那么,上述的两种场景,说了串行,并行两种方式,那么并发呢?

这么说吧,假设计算机是单核的情况下,我此时又想听歌,又想打游戏,该怎么办。按照单核串行的思想来进行理解,我必须要先听完歌,然后才能打游戏,这个很明显不是我所想要的。

那么是否可以这么整,CPU分配个15ms的时间片,先交给音乐方面的线程来执行。然后再分配15ms,再交给游戏线程再来执行,因为中间切换速度很快,我们人类是感觉不到15ms这个间隔的,所以就以为这个执行过程底层是连续的。这就是并发的作用。

如果还不理解,这个例子不太恰当,不过可以按这个方向理解一下。想想英雄联盟中的延迟,就像打游戏我们常说的30延迟,40延迟,以及100延迟这个概念,其实也可以这么理解。为什么会有延迟呢,因为其它的应用占据了对应的CPU,所以没有办法实时反馈结果。只有时间片分配了,才能响应我们的操作。当然,正常情况电脑都是多核的,实际场景也更复杂,只是按照单核的,先理解了这个概念。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值