Java 多线程 超全详细笔记(期末 + 面试完整版)
·
一、进程(Process)
1.1 进程概念
进程:操作系统(OS)中正在运行的应用程序。
现代操作系统支持多进程同时运行,也就是我们常说的多进程机制。 例如:电脑同时运行微信、浏览器、IDEA、音乐软件,每一个软件都是一个独立进程。
1.2 多进程并发执行原理
- 宏观上:并行执行 用户看起来所有程序好像是同时运行。
- 微观上:串行执行 CPU 同一时间只能执行一个进程。 操作系统通过分配 CPU 时间片,快速切换不同进程执行。 谁抢到 CPU 时间片,谁就拥有执行权。
核心原理:快速切换、轮流执行,实现宏观并发效果。
二、线程(Thread)
2.1 线程概念
线程:进程内部的独立执行任务单元。 一个进程可以包含多个线程,多个线程可以同时执行不同任务。
线程也被称为:轻量级进程
- 进程开销大、独立资源多
- 线程依附进程、共享资源、切换速度快
2.2 单线程程序
Java 默认程序是单线程程序
- 程序从
main()方法开始 - 程序随着
main()方法结束而终止 - 这条默认线程称为:主线程
2.3 线程三大组成部分
1)CPU 资源
线程需要抢占 CPU 时间片,抢到时间片才能执行代码。
2)内存数据(核心考点)
- 栈空间:线程独立 每一个线程拥有独立的栈内存,线程之间栈数据互不干扰。
- 堆空间:线程共享 一个进程中的所有线程共享同一个堆内存 所以多线程可以共享对象、数组、集合等堆中数据(也是多线程安全问题的根源)
3)程序代码
通过 Java 代码定义线程任务,由 CPU 调度执行。
三、多线程代码实现方式(第一种:继承 Thread 类)
3.1 实现步骤
- 自定义类继承
java.lang.Thread线程父类 - 重写父类
run()方法线程的所有任务逻辑必须写在 run 方法中
- 创建自定义线程对象
- 调用
start()方法开启线程
3.2 核心重点
run():封装线程任务,手动调用只是普通方法执行,不会开启新线程start():向 JVM 注册线程,开启新线程,由 JVM 自动调用run()执行任务
3.3 执行原理
t.start() → JVM 启动新线程 → 自动执行 run() 方法内容
四、线程状态(等待状态详解)
4.1 线程休眠 sleep
static void sleep(long ms)
- 作用:让当前线程进入限时等待(休眠)状态
- 参数单位:毫秒
- 执行效果:
- 线程主动释放 CPU 资源
- 休眠时间结束后,线程重新进入就绪状态,抢占 CPU 继续执行
4.2 线程加入 join
join():无限等待- 当前线程等待调用 join 的线程执行完毕后,再继续执行
- 用于控制线程执行顺序
区别总结: sleep:限时等待、自动唤醒 join:无限等待、对方线程结束才唤醒
五、线程池(重点、面试必考)
5.1 线程池概念
线程池:线程容器 提前创建若干线程对象存入池中,任务提交后直接分配空闲线程执行,线程执行完毕不会销毁,可重复复用。
5.2 线程池核心好处
- 避免频繁创建、销毁线程,节省系统资源
- 大幅提高执行效率
- 统一管理线程数量,防止并发过多导致系统崩溃
5.3 线程池核心体系(位于 java.util.concurrent 并发包)
1)Executor
线程池顶级根接口,定义线程池最基本机制
2)ExecutorService
Executor 的子接口,线程池核心功能接口 提供线程任务提交、线程池关闭等核心方法
核心方法
submit(Runnable task)提交普通线程任务,无返回值submit(Callable<T> task)提交带返回值的线程任务shutdown()关闭线程池,销毁所有线程对象,不再接收新任务
3)Executors
线程池工具类,提供大量静态方法,快速获取线程池对象
常用线程池
static ExecutorService newFixedThreadPool(int n)固定线程池 创建指定数量的线程,线程数量固定,可复用static ExecutorService newCachedThreadPool()动态缓存线程池 任务多自动新建线程、任务少自动回收空闲线程,线程数量动态变化
六、多线程第二种实现方式:Callable 接口(带返回值)
6.1 Callable 介绍
- 位于
java.util.concurrent并发包 - 作用:和 Runnable 类似,封装线程任务
- 区别于 Runnable:支持返回值、支持抛出异常
- 属于泛型接口,泛型约束返回值类型
6.2 核心方法
V call() throws Exception
- 线程任务方法
- 带有返回值
- 可以抛出异常
6.3 Future 接收线程返回值
Future<T>:用于接收线程执行完毕后的返回结果- 线程池提交任务返回 Future 对象
- 通过
future.get()获取线程最终执行结果
6.4 执行流程
- 自定义类实现 Callable 接口
- 重写 call () 方法,定义任务、返回结果
- 线程池调用 submit () 提交任务
- 返回 Future 对象
- 调用
get()获取线程返回值
七、本章核心考点总结(背诵版)
- 进程是程序,线程是进程中的执行单元,线程轻量级、开销更小
- 进程独占资源,线程共享堆、独立栈
- 宏观并行、微观串行是 CPU 时间片轮换机制
- Thread 类实现线程必须重写 run (),start () 开启新线程
- sleep 限时等待、join 无限等待
- 线程池核心:线程复用、减少开销、提高效率
- Executors 工具类创建线程池、ExecutorService 操作线程池
- Runnable 无返回值,Callable 带返回值、可抛异常
- Future 用于接收 Callable 线程返回结果
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐


所有评论(0)