graph TD
A[新建 New] -->|start| B[就绪 Runnable]
B -->|cpu分配时间片| C[运行 Running]
C -->|cpu分配时间片用完| B
C -->|Object.wait Thread.join 或 LockSupport.park| E[等待 Waiting]
C -->|进入synchronized代码块没有获取到锁| D[阻塞 Blocked]
C -->| Thread.sleep的超时方法或 Object.wait的超时方法和join超时方法等| F[超时等待 Timed_Waiting]
D -->|获取monitor锁| B
E -->|lockSpport.unpark/join程序执行结束| B
E -->|notify/notifyAll| D
F -->|notify/notifyAll| D
F -->|lockSpport.unpark/join程序执行结束| B
C -->|run结束或异常终止| G[终止 Terminated]
线程状态流程图(如上所示)
新建(New):当创建一个 Thread 对象,但还未调用 start 方法时,线程处于新建状态。此时线程对象已经被分配了内存,初始化了其成员变量,但还未与操作系统线程关联。
就绪(Runnable):调用 start 方法后,线程进入就绪状态。此时线程已经具备了运行的条件,但还没有被操作系统调度器分配 CPU 时间片。在就绪队列中的线程处于等待被调度的状态。
运行(Running):当操作系统调度器为线程分配了 CPU 时间片后,线程进入运行状态,开始执行 run 方法中的代码。在运行过程中,线程可能因为以下几种情况转换到其他状态:
- 时间片用完:线程的 CPU 时间片用完后,会重新回到就绪状态,等待再次被调度。
- 调用阻塞方法:如调用 wait、sleep、join 等方法,线程会进入阻塞(等待/超时等待)状态。
- 获取锁失败:当线程尝试获取一个被其他线程持有的锁时,会进入阻塞状态。
阻塞(Blocked):线程因等待某个条件(如获取锁、IO 操作完成等)而暂停执行。处于阻塞状态的线程不占用 CPU 资源。例如,当线程调用 synchronized 块尝试获取锁时,如果锁已被占用,线程就会进入阻塞状态,直到获取到锁才会重新回到就绪状态。
等待(Waiting):当线程调用 Object.wait()、Thread.join() 或 LockSupport.park() 等方法时,线程进入等待状态。处于等待状态的线程需要等待其他线程执行特定操作来唤醒它,如调用 Object.notify() 或 Object.notifyAll() 来唤醒 wait 状态的线程。
超时等待(Timed-Waiting):与等待状态类似,但可以指定一个超时时间。例如调用 Thread.sleep(long millis)、Object.wait(long timeout) 等方法,在指定的时间内线程处于超时等待状态,时间到达后线程会自动唤醒进入就绪状态。
终止(Terminated):当线程的 run 方法执行完毕,或者因异常终止时,线程进入终止状态。此时线程的生命周期结束,所占用的资源会被系统回收。