Java线程的生命周期包括几个不同的状态,线程可以在这些状态之间转换。Java线程的状态转换通常由线程自身的行为和调度器(scheduler)的决定来触发。以下是Java线程的生命周期及其状态转换:
- 新建(New):当线程实例被创建但没有调用
start()
方法时,线程处于新建状态。 - 就绪(Runnable):当线程的
start()
方法被调用后,线程进入就绪状态。此时,线程已经准备好运行,等待被调度器选中并分配CPU资源。 - 运行(Running):当调度器选中就绪状态的线程时,线程开始执行并进入运行状态。线程在此状态时,会在CPU上执行指令。
- 阻塞(Blocked):线程可能会因为等待某些资源或因为同步锁而被阻塞。处于阻塞状态的线程不会执行任何指令。
- 等待(Waiting):线程进入等待状态是因为它调用了
Object.wait()
、Thread.join()
或LockSupport.park()
等方法。在等待状态的线程不会执行任何指令,直到另一个线程执行了相应的通知方法(如Object.notify()
或Object.notifyAll()
)。 - 计时等待(Timed Waiting):线程进入计时等待状态是因为它调用了带有超时的
wait()
、join()
方法,或者使用了ScheduledExecutorService
等。计时等待状态的线程会在指定的时间等待,之后会转换为就绪状态。 - 终止(Terminated):当线程的
run()
方法执行完成后,线程进入终止状态。一旦线程进入终止状态,它就不能被重新启动。
线程状态转换的示例:
- 新建 -> 就绪:调用
start()
方法。 - 就绪 -> 运行:调度器选择该线程并分配CPU资源。
- 运行 -> 阻塞:线程尝试获取一个已由其他线程持有的锁。
- 运行 -> 等待:调用
wait()
方法。 - 运行/阻塞/等待 -> 计时等待:调用带有超时的
wait()
或join()
方法。 - 计时等待 -> 就绪:超时时间到达或被
notify()
/notifyAll()
唤醒。 - 阻塞 -> 就绪:锁被释放,线程重新进入就绪状态。
等待/计时等待 -> 终止:被notify()
/notifyAll()
唤醒,并且run()
方法执行完成。
线程的生命周期和状态转换是由Java线程调度器和线程自身的行为共同决定的。理解线程的生命周期对于开发多线程应用程序非常重要,因为它有助于确保线程的正确创建、管理和生活周期控制。