java的线程状态分为六种
-
新建 NEW
-
当一个线程对象被创建,但是还没有调用start方法时处于新建状态
-
此时未与操作系统底层线程关联
-
-
可运行 RUNNABLE
-
调用了start方法,就会由新建进入可运行状态
-
此时与底层线程关联,由操作系统调度执行
-
(可以细分为准备和运行)准备就是进入了可以得到cpu,但是还没有得到cpu时间片
-
运行就是得到cpu时间片正在执行代码
-
-
终结 TERMINATED
-
线程内代码执行完毕,由可运行进入终结
-
此时会取消与底层线程关联
-
-
阻塞 BLOCKED
-
当获取锁失败后,由可运行状态进入阻塞,此时不占用cpu时间
-
当锁释放后,会按照一定规则唤醒阻塞队列中阻塞的多个线程,重新获取锁
-
得到锁的线程进入可运行状态, 没有得到锁的进入阻塞状态
-
-
等待 WAITING
-
当获取锁成功后,由于条件不满足,调用Object对象的wait()方法,释放锁,此时从可运行状态进入到等待状态,同样不扎弄cpu时间
-
当其他锁线程调用notify()或notifyAll()方法,会按照一定规则唤醒等待集合中党的线程,然后获取锁,
-
如果没有获取到就进入阻塞状态,如果获取到锁就进入可运行状态
-
-
有时限等待 TIME_WAITING
-
当获取锁成功后,但由于条件不满足,调用wait(long) 方法,此时从可运行状态释放锁进入 有时限等待状态,同样不占用cpu
-
当其他持有锁的线程调用当其他锁线程调用notify()或notifyAll()方法,会按照一定规则唤醒等待集合中的线程,然后获取锁,如果没有获取到就进入阻塞状态,如果获取到锁就进入可运行状态
-
如果等待超时,也会从有时限的等待状态到可运行状态,重新去竞争锁
-
还有一种情况是,调用线程的sleep(long) 方法也会从可运行状态进入有时限等待状态,这个时候没有释放锁,不需要主动唤醒,超过时间自动恢复为可运行状态
-
五种状态的说法来自于操作系统层面的划分
-
运行态:分到 cpu 时间,能真正执行线程内代码的
-
就绪态:有资格分到 cpu 时间,但还未轮到它的
-
阻塞态:没资格分到 cpu 时间的
-
涵盖了 java 状态中提到的阻塞、等待、有时限等待
-
多出了阻塞 I/O(java中阻塞I/O是在可运行状态中包含),指线程在调用阻塞 I/O 时,实际干活由 I/O 设备完成,此时线程无事可做,只能干等
-
新建与终结态:与 java 中同名状态类似