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 和 RUNNING
READY
有资格运行,但还没有被调度
调用线程的 start()方法,进入就绪状态
当前线程 sleep() 方法结束,其他线程 join() 结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态
当前线程时间片用完了,调用当前线程的 yield()方法,当前线程进入就绪状态
锁池里的线程拿到对象锁后,进入就绪状态
RUNNING
线程调度程序选中该线程进行运行
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)
操作系统线程模型
用户态
当线程在用户态下实现时,操作系统是不知道该用户态线程的存在的,仅能看到用户态的进程,而不能看到线程。
程序员需要自己实现线程的数据结构,创建销毁和调度维护,也就是相当于需要实现一个自己的线程调度内核,而这些线程运行在操作系统的一个进程中,最后由操作系统直接对进程进行调度。
graph LR
A[CPU] --> |调度进程| B(进程A)
A --> |调度进程| C(进程B)
B --> E{线程1}
B --> F{线程2}
C --> G{线程3}
C --> H{线程4}
内核态
待续
原文:https://www.cnblogs.com/codeclock/p/13803898.html