
🍃 予枫 :个人主页
📚 个人专栏 : 《Java 从入门到起飞》《读研码农的干货日常》《Java 面试刷题指南》
💻 Debug 这个世界,Return 更好的自己!
引言
面试中被问"进程与线程的区别",你还在翻书找答案?Java线程的生命周期,从新建到终止的6个状态,你能说清每个状态的切换条件吗?本文从底层逻辑拆解进程与线程的核心差异,结合Java实战讲透线程生命周期,附面试官高频追问,帮你面试不慌、工作不踩坑,建议收藏备用!
文章目录
- 引言
- 一、先搞懂:进程与线程的核心区别(面试必答)
-
- [1.1 核心定义(通俗版)](#1.1 核心定义(通俗版))
- [1.2 核心区别(对比表,一目了然)](#1.2 核心区别(对比表,一目了然))
- [1.3 底层逻辑补充(加分项)](#1.3 底层逻辑补充(加分项))
- [1.4 面试官追问环节(高频)](#1.4 面试官追问环节(高频))
- 二、Java中线程的完整生命周期(6个状态,必背)
-
- [2.1 线程生命周期的6个状态(Java官方定义)](#2.1 线程生命周期的6个状态(Java官方定义))
- [2.2 各状态详解(结合场景,好记不混)](#2.2 各状态详解(结合场景,好记不混))
-
- [2.2.1 新建态(NEW)](#2.2.1 新建态(NEW))
- [2.2.2 就绪态(RUNNABLE)](#2.2.2 就绪态(RUNNABLE))
- [2.2.3 阻塞态(BLOCKED)](#2.2.3 阻塞态(BLOCKED))
- [2.2.4 等待态(WAITING)](#2.2.4 等待态(WAITING))
- [2.2.5 超时等待态(TIMED_WAITING)](#2.2.5 超时等待态(TIMED_WAITING))
- [2.2.6 终止态(TERMINATED)](#2.2.6 终止态(TERMINATED))
- [2.4 面试官追问环节(高频)](#2.4 面试官追问环节(高频))
- 三、总结(面试速记)
一、先搞懂:进程与线程的核心区别(面试必答)
进程和线程是操作系统中的核心概念,也是Java面试的高频考点,很多人只记表面区别,却答不出底层逻辑,今天一次性讲透,让你既能应付面试,也能理解实际应用场景。
1.1 核心定义(通俗版)
- 进程:操作系统进行资源分配和调度的基本单位,相当于一个"独立的应用程序",比如你打开的微信、IDEA、浏览器,每个都是一个进程。
- 线程:进程内的执行单元,是CPU调度和执行的基本单位,一个进程可以包含多个线程,比如微信同时接收消息、发送文件、刷新朋友圈,就是多个线程在协同工作。
简单来说:进程是"容器",线程是"容器里的干活的人" ,一个容器里可以有多个干活的人,他们共享容器的资源,却各自独立执行自己的任务。

1.2 核心区别(对比表,一目了然)
| 对比维度 | 进程 | 线程 |
|---|---|---|
| 资源分配 | 独立分配(内存、CPU、文件句柄等) | 共享所属进程的资源 |
| 调度单位 | 操作系统调度的基本单位 | CPU调度和执行的基本单位 |
| 独立性 | 高(一个进程崩溃不影响其他进程) | 低(一个线程崩溃可能导致整个进程崩溃) |
| 切换开销 | 大(需切换进程上下文,消耗资源多) | 小(共享进程资源,切换上下文快) |
| 通信方式 | 复杂(需通过管道、消息队列等) | 简单(可直接共享进程内的内存) |
面试小贴士:回答区别时,不要只念表格,重点突出"资源分配"和"调度单位"两个核心维度,再补充独立性和切换开销,面试官会更认可!
1.3 底层逻辑补充(加分项)
进程之间是"隔离"的,每个进程都有自己独立的地址空间,操作系统会为每个进程分配独立的资源,因此进程之间的通信需要借助外部机制;而线程属于同一个进程,共享进程的地址空间和资源,线程之间的通信只需操作共享内存,效率更高。
比如:打开两个IDEA(两个进程),它们的内存是独立的,一个崩溃不会影响另一个;但同一个IDEA里的多个线程(比如代码编译、自动保存、语法检查),如果其中一个线程崩溃,整个IDEA可能会卡死。
1.4 面试官追问环节(高频)
追问1:为什么Java中线程切换比进程切换开销小?
答:因为线程共享所属进程的地址空间和资源,切换线程时,只需切换线程的上下文(如程序计数器、寄存器、栈指针),无需切换进程的地址空间和资源;而进程切换需要保存当前进程的所有资源状态,加载新进程的资源状态,消耗大量CPU和内存资源,因此开销更大。
追问2:进程和线程的关系,用一个生活例子说明?
答:比如一家餐厅(进程),餐厅有自己的场地、食材、设备(资源);餐厅里的厨师、服务员(线程),他们共享餐厅的资源,各自完成自己的任务(厨师做饭、服务员上菜),一个厨师出错(线程崩溃),可能影响餐厅正常运营(进程异常),但其他餐厅(其他进程)不受影响。
二、Java中线程的完整生命周期(6个状态,必背)
Java中的线程生命周期,是面试中仅次于"进程与线程区别"的高频考点,很多人会混淆"阻塞态"和"等待态",今天结合Java源码和实际场景,讲清每个状态的含义、切换条件和应用场景。
2.1 线程生命周期的6个状态(Java官方定义)
Java线程的生命周期分为6个状态,定义在java.lang.Thread.State枚举中,每个状态对应不同的执行阶段,具体如下:
java
public enum State {
// 新建态:线程刚被创建,尚未启动
NEW,
// 就绪态:线程已启动,等待CPU调度(具备执行条件)
RUNNABLE,
// 阻塞态:线程等待锁,暂时无法执行(如synchronized未获取到锁)
BLOCKED,
// 等待态:线程主动等待,需被其他线程唤醒(无超时时间)
WAITING,
// 超时等待态:线程等待指定时间,超时自动唤醒
TIMED_WAITING,
// 终止态:线程执行完毕或异常终止,生命周期结束
TERMINATED
}

2.2 各状态详解(结合场景,好记不混)
2.2.1 新建态(NEW)
-
含义:当我们创建
Thread对象(如new Thread()),但未调用start()方法时,线程处于新建态。 -
特点:此时线程尚未分配CPU资源,也未执行任何代码,只是一个"对象实例"。
-
示例:
java// 新建态线程 Thread thread = new Thread(() -> { System.out.println("线程执行"); }); // 此时thread.getState() 结果为 NEW
2.2.2 就绪态(RUNNABLE)
- 含义:调用
start()方法后,线程进入就绪态,此时线程具备执行条件,等待CPU调度。 - 特点:线程已经准备好执行,只是等待CPU分配时间片,一旦获得CPU,就会进入运行状态(属于RUNNABLE的子集)。
- 注意:Java中没有单独的"运行态",运行态是就绪态的一种表现形式,当CPU调度到该线程时,线程开始执行
run()方法。
2.2.3 阻塞态(BLOCKED)
-
含义:线程在获取锁(如
synchronized锁)时,若锁被其他线程持有,线程会进入阻塞态,直到获取到锁,才会重新进入就绪态。 -
场景:多线程竞争
synchronized锁时,未获取到锁的线程会进入阻塞态。 -
示例:
java// 定义一个锁对象 Object lock = new Object(); // 线程1持有锁 Thread thread1 = new Thread(() -> { synchronized (lock) { try { Thread.sleep(10000); // 持有锁10秒 } catch (InterruptedException e) { e.printStackTrace(); } } }); // 线程2尝试获取锁,会进入BLOCKED态 Thread thread2 = new Thread(() -> { synchronized (lock) { System.out.println("线程2获取到锁"); } }); thread1.start(); thread2.start(); // 此时thread2.getState() 结果为 BLOCKED
2.2.4 等待态(WAITING)
-
含义:线程主动调用
wait()方法(无超时参数),会进入等待态,此时线程会释放持有的锁,需等待其他线程调用notify()或notifyAll()方法唤醒,才能重新进入就绪态。 -
特点:无超时时间,若没有其他线程唤醒,会一直等待(死等)。
-
示例:
javaThread thread = new Thread(() -> { synchronized (lock) { try { lock.wait(); // 主动进入等待态,释放锁 } catch (InterruptedException e) { e.printStackTrace(); } } });
2.2.5 超时等待态(TIMED_WAITING)
-
含义:线程调用
wait(long timeout)、sleep(long millis)、join(long millis)等带超时参数的方法,会进入超时等待态,等待指定时间后,自动唤醒并进入就绪态;也可以被其他线程提前唤醒。 -
特点:有超时时间,即使没有被唤醒,超时后也会自动恢复就绪态,避免死等。
-
示例:
javaThread thread = new Thread(() -> { try { Thread.sleep(5000); // 超时等待5秒,5秒后自动唤醒 } catch (InterruptedException e) { e.printStackTrace(); } });
2.2.6 终止态(TERMINATED)
-
含义:线程执行完
run()方法,或因异常(如NullPointerException)终止,进入终止态,生命周期结束。 -
特点:线程一旦进入终止态,无法再被启动(调用
start()方法会抛出IllegalThreadStateException)。 -
示例:
javaThread thread = new Thread(() -> { System.out.println("线程执行完毕"); }); thread.start(); // 线程执行完run()方法后,getState() 结果为 TERMINATED
2.4 面试官追问环节(高频)
追问1:Java中BLOCKED和WAITING的区别是什么?
答:核心区别是是否释放锁 和唤醒条件:
- 阻塞态(BLOCKED):线程因竞争锁失败进入,不释放已持有的锁,等待锁被释放后自动唤醒,无需其他线程主动唤醒;
- 等待态(WAITING):线程主动调用
wait()方法进入,会释放持有的锁 ,必须等待其他线程调用notify()或notifyAll()唤醒,否则会一直等待。

追问2:sleep()和wait()的区别,面试常考!
答:3个核心区别,记牢不踩坑:
- 所属类不同:
sleep()是Thread类的静态方法,wait()是Object类的方法; - 锁的释放:
sleep()不会释放锁,wait()会释放持有的锁; - 唤醒方式:
sleep()超时后自动唤醒,wait()需被其他线程唤醒(无超时)或超时唤醒(有超时参数)。
追问3:线程进入TERMINATED状态后,还能调用start()方法重启吗?
答:不能。线程一旦进入终止态,其生命周期就已结束,此时调用start()方法会抛出IllegalThreadStateException异常,因为线程的状态无法从TERMINATED回到新建态或就绪态。
三、总结(面试速记)
- 进程与线程核心区别:进程是资源分配单位,线程是CPU调度单位;线程共享进程资源,切换开销小,独立性低。
- Java线程生命周期6个状态:新建(NEW)→ 就绪(RUNNABLE)→ 阻塞/等待/超时等待 → 终止(TERMINATED),重点区分BLOCKED和WAITING的差异。
- 面试加分项:掌握面试官高频追问(如sleep与wait区别、线程状态切换条件),结合代码示例回答,更具说服力。
建议收藏本文,面试前快速过一遍,轻松应对进程与线程相关考题!
💡 结尾互动:如果觉得本文对你有帮助,欢迎点赞、收藏、评论区留言讨论!你还想了解Java多线程的哪些知识点?比如线程池、synchronized锁机制,评论区告诉我,下期安排!