学会线程状态转换能做什么?
- Java体系和计算机系统联系起来
- 定位问题有理论支持
常说的线程
常说的线程是操作系统层面的线程, 在操作系统层面进程是分配资源的最小单位, 线程是调度的最小单位. 一个进程可以包含多个线程, 所以进程和线程是1 : N
的关系. 线程的具体实现随着操作系统的不同而不同(比如Windows, Linux, MacOSX), 但是他们会提供标准的系统调用
给用户进程调用.
用户进程调用
创建线程的系统调用
, 发生用户态到内核态的变化.
上面所说的线程叫做轻量级进程, 平常用户使用的就是轻量级进程
内核线程
是操作系统提供的更底层的线程的实现, 但是其太过底层, 直接给用户使用会危机到系统的自身安全, 所以就封装了轻量级进程, 它和内核线程
是1 : 1
的关系.
Java线程
在不同的操作系统. 对于底层的线程实现不一样, 这样对Java编译一次, 处处执行
产生破坏. 因此Java封装了各种操作系统底层线程的实现, 最后给Java程序员呈现统一的一种模式. Java会把创建的线程映射到轻量级进程之上, 因此阻塞和唤醒线程都需要操作系统的帮助, 也就是说需要从用户态转到内核态.
在Java中最后对线程的状态抽象出6个, 分别是NEW
,RUNNABLE
,BLOCKED
,WAITING
,TIMED_WAITING
,TERMINATED
.
// State 是 Thread 的内部枚举
public enum State {
// 新建状态
NEW,
// Java可运行状态, 可能在运行, 也可能是等待CPU调用
RUNNABLE,
// 等待获取锁
BLOCKED,
// 一直睡眠,等待被唤醒
WAITING,
// 睡眠一定时间, 可自动结束睡眠和被唤醒
TIMED_WAITING,
// 终止
TERMINATED;
}
关于状态的更多内容可以直接查看 Thread#State 枚举
Java线程状态转化
实际应用
使用jstack
命令查看某个Java进程的线程栈.
上图中是三个线程的状态, 其中第一个是WAITING
, 第二个是RUNNABLE
, 第三个是TIMED_WAITING
.
结束语
线程状态在开发的时候一般是用不到的, 或者说不会显示的判断线程的状态, 比如通过 Thread.getState()
. 它通过是用来定位问题, 进程请求没有一直阻塞, 任务一直得不到处理等. 可以用jstack
命令来查看现在进程内部线程的状态等.