本篇文章主要讲Java线程的6种状态
6种状态:初始状态(new) 、可运行状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)、等待队列
初始状态(New):
进程刚创建,未调用new Thread().start()方法时的状态,进程创建方式
可运行状态(Runnable):
在创建线程并调用start()方法之后,获得CPU运行时间之前的状态
进入Runnable状态的方式:
- 调用线程的start()方法
- 当前线程sleep()方法结束
- 其他线程join()结束
- 等待用户输入完毕(阻塞式IO,拿到IO结果后)
- 当前线程拿到所需锁
- 当前线程时间片耗尽
- 调用当前线程的yield()方法
运行中状态Running
获得CPU运行时间后,运行中的状态
进入Running状态的方式(唯一):
- 操作系统的线程调度程序,从可运行状态的线程池中,选出当前线程去执行;
阻塞状态Blocked
运行中的线程,可以会由于各种原因进入到阻塞状态。如调用sleep()方法让线程睡眠,调用wait()方法让线程等待,调用join()、suspend()方法(已弃用)或者阻塞式IO。
进入阻塞状态的方式:
- 当前线程调用sleep()方法
- 当前线程执行过程中,调用了其他线程的join()方法,当前线程进入阻塞状态
- 等待阻塞式IO时
死亡状态Dead
无论是正常退出(run()方法执行完毕),还是抛出了未捕获的异常,都会导致线程进入Dead状态。
或者是主线程main方法执行完毕
在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常
线程的状态流转图
线程睡眠:sleep()方法
线程睡眠,指的是让当前线程暂停执行,等到指定时间后再恢复执行(Runnable状态)
- 线程睡眠会交出CPU,让给其他线/进程执行
- sleep()方法不会释放锁,即当前线程持有某个对象锁时,即使调用sleep()方法其他线程也无法访问这个对象。
- 调用sleep(),当前线程从Running到blocked,sleep结束,从blocked到Runnable