线程的状态有哪些?它们之间是如何转换的?
Java线程在运行生命周期中主要有五种状态:
- 新建(New):线程对象被创建后就进入了新建状态,例如:Thread thread = new Thread()。
-
就绪(Runnable):当调用线程对象的start()方法(thread.start()),线程就进入就绪状态。就绪状态的线程被调度器(Scheduler)选中后,就会被赋予CPU资源,此时线程便进入了运行(Running)状态。
-
运行(Running):线程获取到CPU资源并执行其run()方法。
-
阻塞(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:等待阻塞(通过调用线程的wait()方法,线程放弃对象锁,进入等待池中,等待notify()/notifyAll()方法的唤醒,或者等待的时间到达,线程重新获得对象锁进入就绪状态);同步阻塞(线程在获取synchronized同步锁失败(因为锁被其他线程所持有),它会进入同步阻塞状态);其他阻塞(通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或超时、或者I/O处理完毕时,线程重新进入就绪状态)。
-
死亡(Dead):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
线程状态的转换关系如下:新建状态通过start()方法转换为就绪状态,就绪状态通过获取CPU资源转换为运行状态,运行状态通过yield()方法可以转换为就绪状态,运行状态通过sleep()、wait()、join()、阻塞I/O或获取不到同步锁可以转换为阻塞状态,阻塞状态解除阻塞后可以转换为就绪状态,运行状态结束生命周期转换为死亡状态。