并发编程: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

文章文档:公众号 字节幺零二四 回复关键字可获取本文文档。

posted @   字节幺零二四  阅读(21)  评论(0)    收藏  举报
编辑推荐:
· 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虚拟机代码是如何一步一步变复杂且难以理解的?
点击右上角即可分享
微信分享提示