最近忙得没能抽专门的时间写博客,但阶段性的复盘一直没有落下。推荐一款列计划、记笔记、写总结的工具:Evernote,也就是众所周知的印象笔记啦,支持网页剪藏、手机同步查看等功能,用好了对于工作学习还是很有帮助的,这是我的使用截图:
现准备对印象笔记上的知识点做进一步的总结,在博客上记录和分享。
话不多说,上干货:Java的线程状态总结
- 创建状态/初始状态(New)
继承Thread或实现Runnable得到一个线程类,并实例化了一个对象,但还没运行线程中代码;
- 就绪状态/可运行状态(Runnable)
调用了start()方法,处于“可运行线程池”,只等待CPU使用权,或重新分配时间片。其它所需资源都已获取。
或者
当前线程sleep()方法结束、其他线程join()方法结束、等待用户输入完成、线程拿到对象锁、当前线程时间片用完调用yield()方法---->就绪状态;
- 运行状态(Running)
获取了CPU使用权,真正执行run()方法;即线程调度程序从“可运行线程池”中选择线程,这是线程进入运行状态的唯一方式;
- 阻塞状态(Blocked)
线程因为某种原因放弃CPU使用权,暂时停止运行:
-
等待阻塞:当前线程执行wait()方法,则 释放所有资源,包括所占有的“锁标志”(wait()和notify() 必须在synchronized方法中调用),JVM将其放入“等待池”,此状态无法自动唤醒,需要其他线程调用notify()或notifyAll()方法才能唤醒(若wait()方法带时间参数,则超时自动唤醒);
-
同步阻塞:当前线程在获取对象的同步锁时,该锁被其他线程占用,JVM将其放入“锁池”;
-
其它阻塞:当前线程执行sleep()方法、其他线程执行join()方法、发出I/O请求(当sleep()方法超时、join()方法等待线程终止或者超时、I/O处理完毕---->就绪状态)
此状态
不释放资源,线程不会释放它的“锁标志”;另外的suspend()后进入“挂起状态”,resume()后进入“就绪状态;”
- 死亡状态(Dead)
-
run()方法正常退出;
-
未捕获的异常终止了run()方法,使线程猝死;
-
判断线程是否存活:isAlive():返回 true---->运行、可运行或阻塞状态/返回 false---->创建或死亡状态
【其它】wait()和sleep()区别:
-
sleep()是Thread类的静态方法,让线程进入休眠状态,让出CPU资源给其他线程,等休眠时间结束重新进入“就绪状态”,与其他线程一起竞争CPU的执行时间。无法改变对象的机锁,当一个synchronized块调用了sleep()方法,线程休眠,但对象机锁没有释放,其它线程依然无法访问此对象; Thread.sleep(0)是“触发操作系统立即重新进行一次CPU竞争”;
-
wait()是对象的方法。。。它和notify()、notifyAll()都只能在同步块或同步方法中使用,而sleep()可以在任何地方使用
简言之,调用sleep()的线程不会释放对象锁,而调用wait()的线程释放对象锁