Java中线程的状态一共有6种:
图片来源于网络
- 新建(New):新建一个线程对象,但没有调用start()方法;从New状态出发后,线程就不会回到New状态
- 运行(Runnable):Java中将正在运行(Running)和就绪(Ready)统称为运行(Runnable)。线程创建后,其他线程若调用了该线程的start()方法,则该线程进入就绪(Ready)状态,等待获取CPU的时间片。而该线程获得CPU时间片后则转变为正在运行(Running)。
就绪(Ready)状态:当没有分配CPU时间片时,线程永远处于就绪(Ready)状态;当调用了start()方法时,线程就进入就绪(Ready)状态;当线程的sleep()方法结束,或其他线程join()结束,等待用户输入完毕又或者某个线程拿到对象锁后,这些线程也会进入就绪状态;当前线程的时间片使用完后,调用当前线程的yield()方法,当前线程也会进入就绪状态,当阻塞状态中等待锁的线程拿到锁后,进入就绪状态。
运行(Running)状态:CPU从线程池中选择一个线程,从而使得该线程处于运行(Running)状态。这也是线程进入运行(Running)状态的唯一方式。 - 阻塞(BLOCKED):线程在运行过程中,会由于各种原因进入阻塞状态:
- 线程通过调用sleep方法进入睡眠状态;
- 线程调用一个在I/O上被阻塞的操作,即该操作在输入输出操作完成之前不会返回到它的调用者;
- 线程试图得到一个锁(synchronized等),而该锁正被其他线程持有;
- 线程在等待某个触发条件;
......
阻塞状态指正在运行的线程没有运行结束,暂时让出了CPU时间片,此时其处于就绪(Ready)状态的线程就可以获取CPU时间片,进入运行状态。
- 等待(Waiting):表示线程等待(或者说挂起),让出CPU资源给其他线程使用
Waiting的线程一般在等待一些特殊的事件,比如通过wait()方法等待的线程在等待notify()方法,而通过join()方法等待的线程则会等待目标线程的终止。一旦等到了期望事件,线程就会再次执行。 - 超时等待(Timed_Wating):处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
- 终止(TERMINATED):表示线程已执行完毕。当线程的run()方法执行完毕,或者主程序的main()函数完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生也就是无法再次回到Runnable状态。举个例子,你在淘宝下了一个订单,订单号相当于线程编号,假如你把这个订单取消了,则这个订单无法恢复,就算重新下单同样的商品订单号也会不一样(不是同一个线程)。在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。