8.线程状态
根据 Java 的Thread.state包,线程一共有六种状态:
- NEW
- RUNNABLE
- BLOCKED
- WAITING
- TIMED_WAITING
- TERMINATED
二、每种状态的含义
1. NEW(新建)
当使用new 关键字创建一个线程对象,但尚未调用其start() 方法时,线程处于新建状态。此时线程还没有开始执行,仅仅是一个对象实例,系统尚未为其分配执行资源。
2. RUNNABLE(就绪)
调用start() 方法后,线程进入就绪状态。处于这个状态的线程,要么正在被 CPU 执行,要么在等待 CPU 资源以便执行。Java 虚拟机的线程调度器会为处于该状态的线程分配执行时间片。
3. BLOCKED(阻塞)
线程在获取同步锁(例如synchronized)时,如果该锁已经被其他线程占用,那么当前线程就会进入阻塞状态。处于阻塞状态的线程会暂停执行,直到它成功获取到锁(由于锁竞争导致的阻塞)。
4. WAITING(等待)
当线程执行以下操作时会进入阻塞状态:
- 调用没有超时参数的Object.wait() 方法。
- 调用没有超时参数的Thread.join() 方法。
- 调用LockSupport.park()方法。
处于等待状态的线程会一直等待,直到其他线程执行特定操作(如调用Object.notify()或Object.notifyAll()唤醒等待的线程,或者join
的目标线程执行完毕等)来将其唤醒。
5. TIMED_WAITING(限时等待)
线程进入限时等待状态的情况如下:
- 调用带超时参数的Thread.sleep() 方法,使线程在指定时间内暂停执行。
- 调用带超时参数的Object.wait() 方法,在等待指定时间后,如果没有被唤醒则自动恢复运行。
- 调用带超时参数的Thread.join() 方法,等待指定时间后,不再等待目标线程执行完毕。
- 调用LockSupport.parkNanos() 或 LockSupport.parkUntil() 等带时间限制的方法。
6. TERMINATED(终止)
线程执行完run() 方法中的所有代码,或者在run() 方法中抛出未捕获的异常导致线程提前结束,此时线程就进入终止状态。处于终止状态的线程不再执行任何代码,也不能再转换到其他状态。
三、状态之间的切换条件
1. NEW -> RUNNABLE
当在新建状态的线程对象上调用start() 方法时,线程从新建状态转换为可运行状态。
2. RUNNABLE -> BLOCKED
当处于可运行状态的线程尝试获取一个被其他线程占用的同步锁(进入synchronized)时,会从可运行状态转换为阻塞状态。
3. RUNNABLE -> WAITING
- 线程调用没有超时参数的Object.wait() 方法时,会释放持有的锁(如果有)并进入等待状态。
- 调用没有超时参数的Thread.join() 方法,等待另一个线程执行完毕,此时当前线程进入等待状态。
- 调用LockSupport.park() 方法,线程进入等待状态。
4. RUNNABLE -> TIMED_WAITING
- 调用Thread.sleep() 方法,线程在指定时间内进入限时等待状态。
- 调用带超时参数的Object.wait() 方法,线程在等待指定时间内处于限时等待状态。
- 调用带超时参数的Thread.join() 方法,在等待指定时间内线程处于限时等待状态。
- 调用LockSupport.parkNanos() 或LockSupport.parkUntil() 方法,线程在指定时间内处于限时等待状态。
5. BLOCKED -> RUNNABLE
当处于阻塞状态的线程获取到它等待的同步锁时,会从阻塞状态转换为可运行状态,继续执行后续代码。
6. WAITING -> RUNNABLE
- 当等待状态的线程被其他线程调用Object.notify() 或者 Object.notifyAll() 唤醒时(针对wait() 方法进入等待状态的情况)。
- 当等待的join 目标线程执行完毕(针对join() 方法进入等待状态的情况)。
- 当其他线程调用LockSupport.unpark() 方法来唤醒处于park() 等待状态的线程时,线程从等待状态转换为可运行状态。
7. TIMED_WAITING -> RUNNABLE
- 当Thread.sleep() 的睡眠时间结束。
- 当Object.wait() 的等待时间结束,且没有被提前唤醒。
- 当Thread.join() 的等待时间结束,且目标线程还未执行完毕。
当LockSupport.parkNanos() 或LockSupport.parkUntil()
的等待时间结束,线程从限时等待状态转换为可运行状态。
8. RUNNABLE -> TERMINATED
当线程的run() 方法执行完毕,或者run() 方法中抛出未捕获的异常时,线程从可运行状态转换为终止状态。