阅读的书籍:《疯狂java讲义》
线程的生命周期中有五个状态:新建,就绪,运行,阻塞,死亡
新建(New):当程序使用new关键字创建了一个线程之后,该线程就处于新建状态
此时和创建一个普通java对象没什么区别,java虚拟机分配内存,并对它进行初始化工作
就绪(Runnable):当线程对象调用了start()方法之后,该线程就处于就绪状态
此时表示线程可以运行,但不是开始运行,就像百米比赛时运动员已经在起跑线上随时准备启动一样,至于发令枪什么时候响就看jvm中的线程调度器怎么调度了。java虚拟机这个时候会为它创建方法调用栈和程序计数器。
运行(Running):处于就绪状态的线程获得了cpu,开始执行run()方法,则该线程处于运行状态
当一个线程开始运行后,除非它耗时很短,否则不可能一直处于运行状态。它在运行中会被中断,从而让别的线程获得执行的机会。至于什么时候中断,就看系统采取什么策略了。
抢占式策略(桌面和服务器操作系统):系统给每个可执行的线程一个小时间段来处理任务,当该时间段用完之后,系统就会剥夺该
线程所占用的资源, 让其他线程获得执行的机会
协作式调度策略(小型设备如手机等):只有当一个线程调用了它的sleep()和yield()方法后才会放弃所占用的资源,即主动放弃
阻塞(Blocked):当发生以下情况时,线程将会进图阻塞状态
- 线程调用sleep()方法
- 线程调用了一个阻塞式IO方法,在该方法返回之前
- 线程试图获得一个同步监视器,但其正被其他线程所持有
- 线程在等待某个通知(notify)
- 程序调用了线程的suspend()方法将线程挂起
当正在执行的线程被阻塞之后,别的线程就可以获得执行的机会。当阻塞状态解除后,线程会重新进入就绪状态,解除的方法和上面是对应的:
- 调用的sleep()方法已经达到了指定的时间
- 阻塞式IO方法已经返回
- 线程成功地获得了同步监视器
- 其他线程发出了一个通知
- 处于挂起状态的线程被调用了resume()方法
死亡(Dead):线程以如下三种方式结束,结束后即为死亡状态
- run()或call()方法执行完成,线程正常结束
- 线程抛出一个未捕获的Error或Exception
- 调用了stop()方法
一些注意事项:
- 不要试图对一个已经死亡的线程调用start()方法
- 启动线程的正确方法是start(),而不是run()