1、java线程分为六种状态(依据是java线程类源代码)
分别是
- 新建
- 当一个线程对象被创建,但还未调用 start 方法时就处于新建状态,此时还未与操作系统底层线程关联,仅仅是个JAVA对象
- 可运行
- 调用了 start 方法,就会由新建进入可运行此时与底层线程关联,由操作系统调度CPU执行
- 终结
- 线程内代码已经执行完毕,由可运行进入终结,此时会取消与底层线程关联,相关资源也会被释放
- 阻塞
- 多个线程之间竞争锁,获取锁失败的线程,由可运行进入 Monitor 的阻塞队列阻塞,此时不占用 cpu 时间片
- 当持锁线程释放锁时,会按照一定规则唤醒阻塞队列中的阻塞线程,唤醒后且抢到锁的线程进入可运行状态;没有获取到锁的线程仍然是阻塞状态
- 等待
- 当获取锁成功后,但由于条件不满足,调用了 wait() 方法,此时从可运行状态释放锁进入 Monitor 等待集合等待(阻塞状态),此时不占用 cpu 时间片
- 当其它持锁线程调用 notify() 或 notifyAll() 方法,会按照一定规则唤醒等待集合中的等待线程,唤醒之后在重新去争抢锁,如果争抢到了则恢复为可运行状态(具体可以参照TestThreadState中的testWaiting()debug看看)
- 有时限
- 等待当获取锁成功后,但由于条件不满足,调用了 wait(long) 方法,此时从可运行状态释放锁进入 Monitor 等待集合进行有时限等待(阻塞状态),此时不占用 cpu 时间
- 当其它持锁线程调用 notify() 或 notifyAll() 方法,会按照一定规则唤醒等待集合中的有时限等待线程,唤醒之后在重新去争抢锁,如果争抢到了则恢复为可运行状态
- 如果等待超时,则去重新去竞争锁,如果竞争到了锁也会变为可运行状态,
- 还有一种情况是调用 sleep(long) 方法也会从可运行状态进入有时限等待状态,但与 Monitor 无关,不需要主动唤醒,超时时间到自然恢复为可运行状态
其它情况(只需了解)
1、可以用 interrupt() 方法打断等待、有时限等待的线程,让它们恢复为可运行状态
2、park,unpark 等方法也可以让线程等待和唤醒
2、操作系统划分五种状态
多出了阻塞 I/O,指线程在调用阻塞 I/O 时,实际活由 I/O 设备完成,此时线程无事可做,只能干等