线程与进程(java)
文章目录
- 线程与进程核心知识学习卡片
- 一、基础概念
- 1. 什么是进程?
- 2. 什么是线程?
- 3. 进程 vs 线程 对比表
- 二、线程状态与生命周期
- Java 中线程的六种状态:
- 三、常见问题解答(FAQ)
- Q1:什么是上下文切换?
- Q2:什么是守护线程?
- Q3:什么是死锁?如何避免?
- Q4:`synchronized` 和 `ReentrantLock` 的区别?
- Q5:`volatile` 关键字的作用是什么?能代替锁吗?
- Q6:`Thread.sleep()` 和 `Object.wait()` 的区别?
- 四、线程池详解
- 1. 为什么要用线程池?
- 2. 核心参数说明
- 3. 工作流程图解
- 4. 常见拒绝策略
- 五、进阶理解
- Java 中的线程模型是哪种?
- 线程池是否应该关闭?如果不关闭会怎样?
- 六、类比与比喻
- 七、推荐学习资料
- ✅ 总结一句话
线程与进程核心知识学习卡片
一、基础概念
1. 什么是进程?
- 是程序的一次执行过程;
- 是资源分配的基本单位;
- 拥有独立的地址空间、堆栈、文件描述符等资源。
2. 什么是线程?
- 是 CPU 调度的基本单位;
- 同一个进程中的多个线程共享资源;
- 创建和切换成本比进程低。
3. 进程 vs 线程 对比表
特性 | 进程 | 线程 |
---|---|---|
资源分配 | 独立拥有资源 | 共享所属进程资源 |
切换代价 | 高 | 低 |
安全性 | 相互隔离 | 易受干扰 |
并发性 | 可并行执行 | 更高效并发 |
二、线程状态与生命周期
Java 中线程的六种状态:
状态 | 描述 |
---|---|
NEW | 线程对象已创建但尚未启动 |
RUNNABLE | 可运行状态(包括正在运行和等待 CPU) |
BLOCKED | 等待获取锁进入 synchronized 代码块或方法 |
WAITING | 等待其他线程唤醒(如调用 Object.wait() ) |
TIMED_WAITING | 在指定时间内等待(如 sleep() , wait(timeout) ) |
TERMINATED | 线程已经结束 |
三、常见问题解答(FAQ)
Q1:什么是上下文切换?
上下文切换是 CPU 从一个线程(或进程)切换到另一个线程的过程。频繁切换会带来性能损耗。
Q2:什么是守护线程?
守护线程是一种为其他线程提供服务的线程,如垃圾回收器。JVM 不会因为守护线程而阻止退出。
Q3:什么是死锁?如何避免?
死锁是多个线程互相等待对方释放资源导致都无法继续执行。
- 避免方式:
- 按固定顺序加锁;
- 使用 tryLock;
- 避免嵌套锁;
Q4:synchronized
和 ReentrantLock
的区别?
特性 | synchronized | ReentrantLock |
---|---|---|
加锁方式 | 自动加锁解锁 | 手动控制 lock/unlock |
尝试锁 | 不支持 | 支持 tryLock |
超时机制 | 不支持 | 支持 |
公平性 | 默认非公平 | 可设置为公平锁 |
Q5:volatile
关键字的作用是什么?能代替锁吗?
volatile
保证变量的可见性和禁止指令重排序,但不保证原子性,不能完全替代锁。
Q6:Thread.sleep()
和 Object.wait()
的区别?
对比点 | Thread.sleep() | Object.wait() |
---|---|---|
是否释放锁 | ❌ 不释放 | ✅ 释放 |
唤醒方式 | 时间到了自动恢复 | 需要调用 notify/notifyAll |
使用前提 | 无 | 必须在同步代码块中调用 |
四、线程池详解
1. 为什么要用线程池?
- 提高响应速度;
- 控制最大并发数;
- 统一管理线程生命周期;
- 减少线程创建销毁开销;
2. 核心参数说明
ThreadPoolExecutor(int corePoolSize, // 核心线程数int maximumPoolSize, // 最大线程数long keepAliveTime, // 非核心线程空闲存活时间TimeUnit unit, // 时间单位BlockingQueue<Runnable> workQueue, // 任务队列ThreadFactory threadFactory, // 线程工厂RejectedExecutionHandler handler) // 拒绝策略
3. 工作流程图解
- 如果当前线程数 < corePoolSize → 新建线程处理;
- 如果 >= corePoolSize 且队列未满 → 加入队列等待;
- 如果队列已满 且线程数 < maxPoolSize → 新建线程处理;
- 如果线程数已达 maxPoolSize 且队列已满 → 触发拒绝策略;
4. 常见拒绝策略
策略 | 描述 |
---|---|
AbortPolicy | 默认策略,抛出异常 |
CallerRunsPolicy | 由调用者线程自己执行该任务 |
DiscardPolicy | 默默丢弃任务 |
DiscardOldestPolicy | 丢弃队列中最老的任务 |
五、进阶理解
Java 中的线程模型是哪种?
Java 使用的是 一对一模型(1:1),每个 Java 线程对应一个 OS 线程。
线程池是否应该关闭?如果不关闭会怎样?
应该关闭线程池,否则可能导致内存泄漏、程序无法正常退出。
正确做法示例:
executor.shutdown();
if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();
}
六、类比与比喻
类比 | 描述 |
---|---|
进程 = 公司 | 拥有自己的地址、员工、资产 |
线程 = 员工 | 共享公司资源,各自工作,崩溃可能影响整个公司 |
线程池 = 外包团队 | 事先准备好人员,按需调用,统一管理 |
七、推荐学习资料
类型 | 推荐内容 |
---|---|
📚 书籍 | 《操作系统导论》《Java并发编程实战》《深入理解计算机系统》 |
🎥 视频 | B站清华大学操作系统课程、极客时间《Java并发编程实战课》 |
🧪 工具 | VS Code + Markdown 插件、Typora、Draw.io(画图) |
✅ 总结一句话
线程和进程是操作系统和并发编程的核心基础,掌握它们的概念、状态、调度、协作机制,是你写出高性能、稳定、安全程序的关键。