并发学习记录01:进程和线程
进程
- 程序是由指令和数据组成,但是这些指令要运行,数据要读写,就必须将指令加载到CPU,数据加载到内存。在指令运行中还需要用到磁盘和网络等系统资源。进程就是用来加载指令,管理内存,管理IO的。
- 当一个程序被运行,从磁盘加载这个程序的部分代码到内存,这时就开启了一个进程
- 进程可以看做程序的一个实例。大部分程序可以运行多个实例进程(如记事本),小部分程序只能启动一个实例(如迅雷)
- 程序是静态的,进程是动态的
线程
- 一个进程之内可以分为一到多个线程
- 一个线程就是一个指令流,将指令流的一条条指令以一定的顺序交给CPU执行
- JAVA中,线程作为最小的调度单位,进程作为资源分配的最小单位。
- 其实最终去执行代码的还是线程
二者对比
- 进程基本上是相互独立的,线程存在于进程的内部,线程属于进程
- 一个进程内部的线程可以共享这个进程的资源,如内存空间等
- 进程间通信较为复杂
- 同一台计算机的进程通信成为IPC
- 不同计算机之间的进程通信,需要通过网络,并遵守共同的协议,如HTTP
- 线程通信相对简单,因为它们共享进程内的内存,多个线程可以访问同一个共享变量
- 线程更加轻量,线程上下文的切换成本一般要比进程上下文的切换成本低。
并行与并发
并发
单核CPU下,线程实际上还是串行执行的。操作系统中有一个组件叫做任务调度器,将CPU的时间片分给不同的程序使用,只是由于CPU在线程间切换的非常快,给人的感觉是同时运行的,总结就是微观上串行,宏观上并行。这种线程轮流使用CPU的做法叫做并发,英文是concurrent。
并行
随着CPU核越来越多,每一个核都可以调度运行线程,这时候线程可以是并行的。
总结:
并发是同一时间段内做多件事情,同一时刻只做一件事情。
并行是同一时刻做多件事情。
应用
应用一:异步调用
从方法调用的角度来讲,如果
- 需要等待结果返回,程序才能运行就是同步调用
- 不需要等待结果返回,就能运行就是异步调用
设计
多线程可以让方法执行变为异步的,比如执行长时间才能完成的操作时,如果没有线程调度机制,这段时间调用者其他什么都做不了。
结论
比如在项目中,某个操作比较耗时而又不影响主线程,就可以开一个线程完成这个耗时的操作,避免阻塞主线程
tomcat的异步servlet也是类似目的,让用户线程处理耗时较长的操作,避免阻塞tomcat的工作线程
ui程序中,开线程进行其他操作,避免阻塞ui线程
应用二:提高效率
假设有多个计算任务,计算任务1需要花费10ms,计算任务2需要花费11ms,计算任务3需要花费9ms,汇总需要1ms。
如果是串行执行,那么总共花费时间为 10 + 11 + 9 + 1 = 31 ms
但是如果是四核CPU,分别开三个线程去执行计算任务1,2,3,这样计算时间只用11ms,加上汇总时间总共用12ms
注意
单核CPU下,多线程不能实际提高程序运行效率,只是为了能够在不同任务之间切换,不同线程轮流使用CPU,不至于一个线程总占用CPU,别的线程没法工作
多核CPU可以并行跑多个线程,但能否提高程序运行效率还是要分情况的。有些任务拆分之后并行执行可以提高程序的运行效率,但不是所有计算任务都能拆分。
IO操作不占用CPU,只是一般拷贝文件用的是阻塞IO,这种情况虽然不用CPU,但是需要等待IO结束,也没能充分利用线程
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现