java线程状态切换.png
1 新建(New)
- 创建后尚未启动
2 可运行(Runnable)
- 可能正在运行,也可能正在等待 CPU 时间片。
- 包含了操作系统线程状态中的 Running 和 Ready。
3 阻塞(Blocking)
等待获取一个排它锁,如果其线程释放了锁就会结束此状态。
- Blocked是阻塞的意思,例如遇到了一个IO操作,此时CPU处于空闲状态,可能会转而把CPU时间片分配给其他线程,这时也可以称为“暂停”状态。
- Blocked状态结束后,进入Runnable状态,等待系统重新分配资源。 出现阻塞的情况大体分为如下5种:
- 线程调用sleep方法,主动放弃占用的处理器资源。
- 线程调用了阻塞式IO方法,在该方法返回前,该线程被阻塞。
- 线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。
- 线程等待某个通知。
- 程序调用了suspend方法将该线程挂起。此方法容易导致死锁,尽量避免使用该方法。
4 无限期等待(Waiting)
进入方法 | 退出方法 |
---|---|
没有设置 Timeout 参数的 Object.wait() 方法 | Object.notify() / Object.notifyAll() |
没有设置 Timeout 参数的 Thread.join() 方法 | 被调用的线程执行完毕 |
LockSupport.park() 方法 | - |
等待其它线程显式地唤醒,否则不会被分配 CPU 时间片。
进入方法 | 退出方法 |
---|---|
没有设置 Timeout 参数的 Object.wait() 方法 | Object.notify() / Object.notifyAll() |
没有设置 Timeout 参数的 Thread.join() 方法 | 被调用的线程执行完毕 |
LockSupport.park() 方法 | - |
5 限期等待(Timed Waiting)
- 无需等待其它线程显式地唤醒,在一定时间之后会被系统自动唤醒。
- 调用 Thread.sleep() 方法使线程进入限期等待状态时,常常用“使一个线程睡眠”进行描述。
- 调用 Object.wait() 方法使线程进入限期等待或者无限期等待时,常常用“挂起一个线程”进行描
进入方法 | 退出方法 |
---|---|
Thread.sleep() 方法 | 时间结束 |
设置了 Timeout 参数的 Object.wait() 方法 | 时间结束 / Object.notify() / Object.notifyAll() |
设置了 Timeout 参数的 Thread.join() 方法 | 时间结束 / 被调用的线程执行完毕 |
LockSupport.parkNanos() 方法 | - |
LockSupport.parkUntil() 方法 | - |
6 死亡(Terminated)
可以是线程结束任务之后自己结束,或者产生了异常而结束
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒后,才会进入就绪队列,等待CPU的调度;反之,一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒。