1. 进程与线程的本质区别
第一次接触多线程编程时,我也曾被进程和线程的概念困扰。直到在电商系统开发中遇到订单超卖问题,才真正理解它们的差异。进程就像独立的超市,而线程则是超市里的收银台 - 这个类比帮我度过了初学阶段。
1.1 内存与资源隔离性
进程拥有独立的虚拟地址空间,这意味着:
- 每个进程的堆、栈和数据段都是隔离的
- 一个进程崩溃不会直接影响其他进程(除非故意设计共享内存)
- 进程间通信必须通过IPC机制(管道、消息队列等)
而线程共享进程的内存空间:
java复制// 示例:多个线程共享同一对象实例
public class SharedCounter {
private int count = 0;
public synchronized void increment() {
count++; // 所有线程操作同一个count变量
}
}
1.2 创建与切换开销对比
在Linux系统上实测数据:
- 进程创建耗时约300-1000微秒
- 线程创建耗时约50-100微秒
- 进程上下文切换需要保存/恢复完整的PCB(进程控制块)
- 线程切换只需保存/恢复程序计数器等少量寄存器
重要提示:在Java中通过ProcessBuilder创建进程的开销远大于new Thread()
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Java线程状态机详解
2.1 六种状态的本质含义
通过jstack工具观察线程状态时,必须理解每种状态背后的运行机制:
-
NEW(新建)
- 仅存在于代码层面:
Thread t = new Thread() - 尚未调用start()方法
- 不占用系统线程资源
- 仅存在于代码层面:
-
RUNNABLE(可运行)
- 包括正在运行和就绪两种子状态
- 可能正在等待CPU时间片(就绪)
- 可能正在执行代码(运行中)
-
BLOCKED(阻塞)
java复制synchronized(lock) { // 如果其他线程持有锁,当前线程进入BLOCKED // 临界区代码 }- 只发生在synchronized锁竞争场景
- 与操作
