携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第16天,点击查看活动详情
Java线程六种状态及转换
-
NEW-新建状态
- 当一个线程对象被创建,在未调用 start() 方法时处于新建状态
- 此时还未与操作系统底层线程关联
-
RUNNABLE-可运行状态
- 调用 start() 方法,线程状态由新建进入可运行
- 此时与底层线程关联,由操作系统调度执行
-
TERMINATED-终结状态
- 整个线程内代码已经执行完毕,由可运行进入终结
- 此时会取消与底层线程关联
-
BLOCKED-阻塞状态
- 当获取锁失败后,由可运行进入 Monitor 的阻塞队列阻塞,此时不占用 cpu 时间
- 当持锁线程释放锁时,会按照一定规则唤醒阻塞队列中的阻塞线程,唤醒后的线程进入可运行状态
-
WAITING-等待状态
- 当获取锁成功后,但由于条件不满足,调用了 wait() 方法,此时从可运行状态释放锁进入 Monitor 等待集合等待,同样不占用 cpu 时间
- 当其它持锁线程调用 notify() 或 notifyAll() 方法,会按照一定规则唤醒等待集合中的等待线程,恢复为可运行状态
-
TIMED_WAITING-有时限等待状态
- 当获取锁成功后,但由于条件不满足,调用了 wait(long) 方法,此时从可运行状态释放锁进入 Monitor 等待集合进行有时限等待,同样不占用 cpu 时间
- 当其它持锁线程调用 notify() 或 notifyAll() 方法,会按照一定规则唤醒等待集合中的有时限等待线程,恢复为可运行状态,并重新去竞争锁
- 如果等待超时,也会从有时限等待状态恢复为可运行状态,并重新去竞争锁
- 还有一种情况是调用 sleep(long) 方法也会从可运行状态进入有时限等待状态,但与 Monitor 无关,不需要主动唤醒,超时时间到自然恢复为可运行状态
操作系统层面的五中状态
-
运行态:分到 cpu 时间,能真正执行线程内代码的
-
就绪态:有资格分到 cpu 时间,但还未轮到它的
-
阻塞态:没资格分到 cpu 时间的
- 包含 java 状态中的阻塞、等待、有时限等待
- 多出了阻塞 I/O,指线程在调用阻塞 I/O 时,实际活由 I/O 设备完成,此时线程无事可做,只能干等
-
新建与终结态:与 java 中新建、终结状态一致