JVM自定义线程状态原因
对线程状态进行了统一,屏蔽了不同操作系统对线程状态的不同定义。
A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.
线程状态
状态项
NEW: 新创建还未开始运行;
RUNNABLE: CPU正在执行、等待CPU执行、IO阻塞;
BLOCKED: 阻塞状态,等待竞争对象锁;
WAITING: 无时间限制的等待,等待被其它线程唤醒;
TIMED_WAITING: 有时间限制的等待,等待被其它线程唤醒;
TERMINATED: 运行完成;
处于WAITING状态的几种情况:
Case1: Object.wait();
Case2: Thread.join();
Case3: LockSupport.park();
处于TIMED_WAITING状态的几种情况:
Case1: Object.wait(long);
Case2: Thread.join(long);
Case3: LockSupport.parkNanos();
Case4: LockSupport.parkUntil();
Case5: Thread.sleep(long);
IO阻塞时JVM线程状态
RUNNABLE状态,测试代码如下:
public class IOBlockTest {
public static final int PORT = 10000;// 监听的端口号
public static void main(String[] args) {
for (int i = 1; i <= 3000; ++i) {
final int j = i;
Thread t1 = new Thread(() -> {
try {
ServerSocket serverSocket = new ServerSocket(PORT + j);
while (true) {
Socket client = serverSocket.accept();
System.out.println("accept...\n");
}
} catch (Exception e) {
System.out.println("服务器异常: " + e.getMessage());
}
});
t1.setName("Server_" + i);
t1.start();
}
}
}
线程堆栈信息如下:
"Server_6" #1015 prio=5 os_prio=0 tid=0x000000005a897800 nid=0xe910 runnable [0x00000000ab49f000]
java.lang.Thread.State: RUNNABLE
at java.net.DualStackPlainSocketImpl.accept0(Native Method)
at java.net.DualStackPlainSocketImpl.socketAccept(Unknown Source)
at java.net.AbstractPlainSocketImpl.accept(Unknown Source)
at java.net.PlainSocketImpl.accept(Unknown Source)
- locked <0x00000000ff54d330> (a java.net.SocksSocketImpl)
at java.net.ServerSocket.implAccept(Unknown Source)
at java.net.ServerSocket.accept(Unknown Source)
at Server.lambda$1(Server.java:27)
at Server$$Lambda$2/303563356.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
JVM线程状态与传统操作系统线程状态的对应关系
JVM线程的RUNNABLE 状态对应了传统的 ready, running 以及部分的 waiting 状态,BLOCKED 、WAITING、TIMED_WAITING状态均是传统 waiting 状态的一个细分,如下图所示:
IO阻塞的底层机制
当JVM线程发生IO阻塞时,对应操作系统的线程进入waiting队列,不再占用CPU,CPU会从ready队列中选择线程执行,当硬件驱动完成IO操作后发出中断信号通知CPU,执行中断程序,正在被CPU执行的线程进入ready队列,之前因 I/O 阻塞而进入waiting 的线程随再次回到 ready 队列。