多线程中级篇(1) 线程状态
条评论线程状态
一个新线程启动后,从开始运行一直到最后任务执行完成销毁这个线程,在整个线程生命周期中有哪几个状态,各个状态之间如何流转,本文将给出详细解释。
线程状态迁移
下面的这个线程状态迁移图是比较经典的,画的很详细,理解了这幅图就理解了线程状态变化。

线程的几个状态
- [new]:初始状态,新建一个线程对象后的状态;
- [runnable]:就绪状态,调用了start()方法后,线程等待CPU资源准备执行的状态;
- [running]:运行状态,得到了CPU时间片,执行run()方法或者call()方法;
- [dead]:销毁状态,线程任务执行结束或者强制退出后的状态;
- [blocked]:阻塞状态,被动失去CPU时间片,等待进入runnable状态;
- [waiting]:等待状态,主动失去CPU时间片,等待进入runnable状态;
waiting状态和blocked状态的区别在于一个是主动交出时间片,另外一个是被动交出时间片;当然前提是已经获得了时间片开始执行;从runnable状态到running状态是不受程序控制的,完全靠操作系统来调度,虽然我们可以设置线程的优先级,但是不一定达到预期。
状态变化过程
- [new]:MyThread thread = new MyThread();
- [new]->[runnable]:thread.start();
- [runnable]->[running]:操作系统调度,runnable状态意味着任务已经做好执行的准备,但什么时间真正执行(获得时间片)需要由操作系统来控制,任务本身无法控制;
- [running]->[dead]:线程执行完成;
- [running]->[runnable]:
- Thread.yield(); 调用yield()方法将失去时间片,但是可以立刻进入runnable状态,运气好的话可以立刻又获得时间片进入running状态;yield()给其他任务以执行的机会;
- [running]->[waiting]:
- thread.join();调用join()方法将失去时间片,进入waiting状态,等到thread线程执行完毕后进入runnable状态;
- object.wait(); 调用 wait()方法将失去时间片,进入waiting状态,得到其他线程执行object.notify()方法是进入runnable状态;
- Thread.sleep(); 调用sleep()方法将失去时间片,进入waiting状态,sleep结束后进入runnable状态;
- [running]->[blocked]:进入synchronized(object){}语句块前检查object锁,如果object已经被锁定,那么当前线程进入blocked状态,当object锁被释放后,当前线程进入runnable状态;
- [waiting]->[runnable]:
- thread.join(); 引发的,其他线程执行完成后进入runnable状态;
- object.wait(); 引发的,其他线程调用object.notify()或者object.notifyAll()后进入runnable状态;
- [blocked]->[runnable]:其他线程退出synchronized{}语句块以后进入runnable状态;
我们再通过表格的形式来看一下线程状态变化过程
| 方法调用 | 线程旧状态 | 线程新状态 | 备注 |
|---|---|---|---|
| new Thread(); | new | ||
| thread.start(); | new | runnable | |
| Thread.yield(); | running | runnable | |
| thread.join(); | running | waiting | |
| Thread.sleep(); | running | waiting | |
| object.wait(); | running | waiting | |
| synchronized(object){} | running | blocked | |
| thread.interrupt(); | running | dead | |
| 子线程执行完成 | waiting | runnable | 外部线程 |
| Sleep()时间到 | waiting | runnable | |
| object.notify()或notifyAll(); | waiting | runnable | 外部线程 |
| 退出synchronized代码块 | blocked | runnable | 外部线程 |
个人理解,waiting状态和blocked状态的区别并不大,粗一点的话可以不区分它们。
相关方法
Thread类和Object类相关方法
注意:区分Thread类和Object类的方法,区分静态方法和普通方法。
package java.lang; |
package java.lang; |
以上可以看出,所有的关键方法都是native的,基于系统底层实现的。