Java线程的状态以及转换
状态转换图
java线程的状态概述
(1)新建状态:当刚刚开始new 一个线程对象所处的状态
(2)可运行状态:当调用创建对象的start()方法时所处的状态,处于该状态的线程位于可运行线程池中,等待被OS的线程调度选中,获取cpu使用权。
(3)运行状态:调用start()方法后并获得cpu,开始执行代码
(4) 阻塞状态:线程放弃cpu使用权,暂停停止运行,直到线程进入可运行状态,才有可能再次获取cpu使用权。
- 等待阻塞
运行的线程执行wait()方法,JVM会把该线程放入等待队列中。
- 同步阻塞
运行的线程在获取对象的同步锁时,该同步锁被别的线程占用,JVM则会把该线程放入放入锁池中.
- 其他阻塞
运行的线程执行Thread.sleep(long ms)或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
(5)死亡状态:线程run(),main()方法执行结束或者因为异常退出run()方法,该线程结束生命周期,死亡的线程不可以再次复生。
出现五种状态的可能情况
-
新建状态:
实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了新建状态 -
可运行状态
(1)调用线程的start()方法,此线程进入可运行状态
(2)当前线程sleep()方法结束,此线程进入可运行状态
(3)其他线程join()结束,此线程进入可运行状态
(4)等待用户输入完毕,此线程进入可运行状态
(5)某个线程拿到对象锁,此线程进入可运行状态
(6)当前线程时间片 用完了但线程还没有结束,此线程进入可运行状态时间片:一个线程一次被选中,执行的时间时有限的,这个时间段叫做CPU的时间片
(7)调用当前线程的yield()方法,当前线程进入可运行状态。
(8)锁池里的线程拿到对象锁后,进入可运行状态。 -
运行状态:
线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一方式。 -
阻塞状态:
(1)在一个运行中的线程等待用户输入,则当前线程变为阻塞状态。
(2)调用Thread.sleep(),则当前线程变为阻塞状态。
(3)调用了其他线程的join()方法,则当前线程变为阻塞状态。 -
死亡状态:
当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。死亡的线程不能复生。
绝不能在一个死去的线程上调用start()方法,会抛出异常 -
等待队列:
在线程中调用wait()方法,进入等待状态
-
锁池状态:
运行中的线程遇到synchronized同时没有拿到对象的锁标记、等待队列的线程wait时间到、等待队列的线程被notify方法唤醒、有其他线程调用notifyAll方法,则线程变成锁池状态。