Java线程状态 与 操作系统线程状态
Java 线程中几个状态说明
定义在Thread类中的 State枚举中,可以直接查看代码中的注释
java.lang.Thread
. State . NEW | RUNNABLE | BLOCKED | WAITING | TIMED_WAITING | TERMINATED
状态 | 解释 | 说明 |
---|---|---|
NEW | 新建一个线程对象,还没有调用start()方法 | new一个线程实例,线程还没有start |
RUNNABLE | Java线程中将就绪(READY)和运行中(RUNNING)两种状态统一为 RUNABLE | 等待被调度或正在运行中 |
BLOCKED | 表示线程阻塞于锁 | 线程阻塞在进入synchronized修饰的方法或代码块时的状态 |
WAITING | 进行该状态的线程需要等待其他线程做出一些特定动作(通知或中断) | 让出CPU,等待被显示的唤醒,被唤醒后进入BLOCKED状态,重新获取锁 |
TIMED_WAITING | 不同于waiting,它可以在指定的时间后自行返回 | 超时等待,让出CPU,时间到了自动唤醒,进入BLOCKED状态,重新获取锁 |
TERMINATED | 表示显示已经执行完毕 |
RUNNABLE
Java中 RUNNABLE 对应操作系统的几个状态
-
READY
- 有资格运行,但还没有被调度
- 调用线程的 start()方法,进入就绪状态
- 当前线程 sleep() 方法结束,其他线程 join() 结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态
- 当前线程时间片用完了,调用当前线程的 yield()方法,当前线程进入就绪状态
- 锁池里的线程拿到对象锁后,进入就绪状态
-
RUNNING
线程调度程序选中该线程进行运行
-
操作系统线程阻塞等待 I/O
JVM 并不关心操作系统线程的实际状态,从 JVM 看来,等待CPU使用权(操作系统状态为可运行态)与等待 I/O(操作系统处于等待状态)没有区别,都是在等待某种资源,所以都归入RUNNABLE 状态
BLOCKED
由synchronized锁导致进入该状态(WAITING,TIMED_WAITING状态下唤醒也可能进入该状态)
(Java中的 BLOCKED状态与操作系统中的 阻塞状态不同)
WAITING
各情况下进入该状态,线程不会占用CPU,线程会让出锁,等待被其他线程唤醒,然后会进入 BLOCKED 状态,重新竞争锁。
TIMED_WAITING
各个情况下进入该状态,线程不会占用CPU,时间到了自动唤醒
-
如果是因为sleep进入该状态,线程不会释放锁,等到时间到了自动唤醒进入RUNNABLE状态
-
其他情况下线程会释放锁,等待其他线程唤醒,超时时间到了自动唤醒,然后进入 BLOCKED状态,重新竞争锁
TERMINATED
线程 run()方法完成时,或者主线程main()方法结束时,就认为它终止了。
这个线程对象也许是活的,但是已经不是一个单独执行的线程了,线程一旦终止了就不能复生,在一个终止的线程上调用 start()方法,会抛出 java.lang.IllegalThreadStateException
异常
下面是 Java中线程的状态,不是操作系统中线程的状态
Java 中的线程与操作系统中线程的区别
操作系统中进程(线程)的状态有:
-
初始状态(NEW)
对应 Java中的
-
可运行状态(READY)
对应 Java中的 RUNNBALE 状态
-
运行状态(RUNNING)
对应 Java中的 RUNNBALE 状态
-
等待状态(WAITING)
该状态在 Java中被划分为了 BLOCKED,WAITING,TIMED_WAITING 三种状态
当线程调用阻塞式 API时,进程(线程)进入等待状态,这里指的是操作系统层面的。从 JVM层面来说,Java线程仍然处于 RUNNABLE 状态。
JVM 并不关心操作系统线程的实际状态,从 JVM 看来,等待CPU使用权(操作系统状态为可运行态)与等待 I/O(操作系统处于等待状态)没有区别,都是在等待某种资源,所以都归入RUNNABLE 状态
-
终止状态 (TERMINATED)
参考博客