并发编程:Java线程状态及其转换
线程状态
操作系统层面,线程分为五种状态
- 创建状态:线程正在被创建,包括申请资源、分配空间等操作。
- 就绪状态:已获得除 CPU 外的一切所需资源。
- 运行状态:获得 CPU 正在运行。
- 阻塞状态:因等待某一事件而暂停运行,如等待 I/O 操作完成。
- 终止状态:执行完毕,正在进行资源释放等操作。
Java API 层面,线程分为六种状态
-
NEW:语言层面创建了线程对象,未与操作系统线程关联。
Thread state for a thread which has not yet started.
-
RUNNABLE:start()方法被调用,涵盖操作系统层面的就绪、运行、阻塞状态。
Thread state for a runnable thread.
A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor. -
BLOCKED:等待Monitor锁。
Thread state for a thread blocked waiting for a monitor lock.
A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling. -
WAITING:等待其他线程执行特定操作使得当前线程满足继续执行的条件,此处条件通常是人为设定的。
Thread state for a waiting thread.
A thread is in the waiting state due to calling one of the following methods: Object.wait, Thread.join, LockSupport.park.
A thread in the waiting state is waiting for another thread to perform a particular action. -
TIMED_WAITING:待时限的WAITING状态。
Thread state for a waiting thread with a specified waiting time.
A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time: Object.wait, Thread.join, LockSupport.parkNanos, LockSupport.parkUntil. -
TERMINATED:执行完毕。
Thread state for a terminated thread.
The thread has completed execution.
无特别说明,以下所涉及的线程状态均指 Java API 层面的状态。
NEW ==> RUNNABLE
当调用 t.start() 方法时,线程 t 的状态由 NEW 转为 RUNNABLE。
RUNNABLE <==> WAITING
wait & notify
线程 t 执行 synchronized(obj) 后,调用 obj.wait() 方法
- 线程 t 由 RUNNABLE 转为 WAITING
- 其他线程调用 obj.notify()、obj.notifyAll()、t.interrupt()
- 线程 t 若竞争锁成功,则由 WAITING 转为 RUNNABLE。
- 线程 t 若竞争锁失败,则由 WAITING 转为 BLOCKED。
join
当前线程调用 t.join() 方法
- 当前线程从 RUNNABLE 转为 WAITING。
- 线程 t 执行完毕或当前线程的 interrupt() 方法被调用,当前线程从 WAITING 转为 RUNNABLE。
park & unpark
线程 t 调用 LockSupport.park() 方法
- 线程 t 从 RUNNABLE 转为 WAITING。
- 调用 LockSupport.unpark(t) ,或调用 t.interrupt() 方法,线程 t 从 WAITING 转为 RUNNABLE。
RUNNABLE <==> TIMED_WAITING
和 RUNNABLE 与 WAITING之间的转换类似,TIMED_WAITING 是带时限的 WAITING。
线程 t 执行 synchronized(obj) 后,调用 obj.wait(long) 方法
- 线程 t 由 RUNNABLE 转为 WAITING
- 线程 t 等待超时,或其他线程调用 obj.notify()、obj.notifyAll()、t.interrupt()
- 线程 t 若竞争锁成功,则由 WAITING 转为 RUNNABLE。
- 线程 t 若竞争锁失败,则由 WAITING 转为 BLOCKED。
join
当前线程调用 t.join(long) 方法
- 当前线程从 RUNNABLE 转为 WAITING。
- 线程 t 执行完毕,或当前线程等待超时,或当前线程的 interrupt() 方法被调用,当前线程从 WAITING 转为 RUNNABLE。
park & unpark
线程 t 调用 LockSupport.parkNanos(long) 或 LockSupport.parkUntil(long) 方法
- 线程 t 从 RUNNABLE 转为 WAITING。
- 调用 LockSupport.unpark(t) ,或线程 t 等待超时,或调用 t.interrupt() 方法,线程 t 从 WAITING 转为 RUNNABLE。
sleep
线程 t 调用 Thread.sleep(long)
- 线程 t 从 WAITING 转为 RUNNABLE。
- 线程 t 等待超时,或调用 t.interrupt() 方法,线程 t 从 WAITING 转为 RUNNABLE。
RUNNABLE <==> BLOCKED
- 线程 t 竞争锁失败,从 RUNNABLE 转为 BLOCKED。
- 线程 t 竞争锁成功,从 BLOCKED 转为 RUNNABLE。
RUNNABLE ==> TERMINATED
线程 t 执行完毕,从 RUNNABLE 转为 TERMINATED。
状态辨析
BLOCKED 和 WAITING/TIMED_WAITING
- 存放:BLOCKED 状态的线程存放在 Monitor 对象的 EntryList 中,WAITING 状态的线程存放在 Monitor 对象的 WaitSet 中。
- 等待:BLOCKED 状态的线程在等待锁,WAITING 状态的线程在等待人为设置的条件成立,或者说在等待其他线程将其唤醒。
- 调度:BLOCKED 可被 CPU 调用,WAITING 状态的线程只有被其他线程唤醒后才能被 CPU 调度。
操作系统的 BLOCKED 和 Java API 的 BLOCKED
- 操作系统的 BLOCKED,指线程正在等待某种资源(如打印机)或者等待某个操作完成(如 I/O)。
- Java API 的 BLOCKED,指线程正在等待锁。
END
文章文档:公众号 字节幺零二四
回复关键字可获取本文文档。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】凌霞软件回馈社区,携手博客园推出1Panel与Halo联合会员
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· dotnet 9 通过 AppHostRelativeDotNet 指定自定义的运行时路径
· 如何统计不同电话号码的个数?—位图法
· C#高性能开发之类型系统:从 C# 7.0 到 C# 14 的类型系统演进全景
· 从零实现富文本编辑器#3-基于Delta的线性数据结构模型
· 记一次 .NET某旅行社酒店管理系统 卡死分析
· 用c#从头写一个AI agent,实现企业内部自然语言数据统计分析
· 三维装箱问题(3D Bin Packing Problem, 3D-BPP)
· Windows上,10分钟构建一个本地知识库
· 使用 AOT 编译保护 .NET 核心逻辑,同时支持第三方扩展
· Java虚拟机代码是如何一步一步变复杂且难以理解的?