Java的每个线程都具备本人的状态,Thread类中成员变量threadStatus存储了线程的状态:
private volatile int threadStatus = 0;
在Thread类中也定义了状态的枚举,共六种,如下:
public enum State {
NEW, // 新建状态
RUNNABLE, // 执行状态
BLOCKED, // 阻塞状态
WAITING, // 无限期期待状态
TIMED_WAITING, // 有限期期待状态
TERMINATED; // 退出状态
}
threadStatus初始值为0,对应的就是NEW状态。
- NEW:新建状态,new Thread()时处于这个状态,此时线程还未开始执行
- RUNNABLE:执行状态,当调用了start办法后,线程处于此状态,当然此刻CPU不肯定正在执行它
- BLOCKED:阻塞状态,线程期待锁时处于此状态
- WAITING:无限期期待状态,须要被唤醒的期待属于此状态,如Object.wait
- TIMED_WAITING:有限期期待状态,调用一些有超时工夫的期待办法会进入此状态,如Thread.sleep、Object.wait、Thread.join、Lock.tryLock、Condition.await
- TERMINATED:退出状态,可能是失常运行结束,也可能是抛出了异样导致线程终止
咱们能够通过getState获取线程的状态:
State state = thread.getState();
接下来,咱们通过示例来感触线程状态的变动。
示例一:
Thread t = new Thread(() -> {
System.out.println("sleep");
// 休眠2秒
ThreadUtil.sleep(2000);
System.out.println("run");
});
// 启动前先打印一下线程状态
System.out.println(t.getState());
// 启动线程
t.start();
// 启动后立刻打印一次线程状态
System.out.println(t.getState());
// 每隔500毫秒打印一次线程状态
while (true) {
ThreadUtil.sleep(500);
System.out.println(t.getState());
}
输入:
NEW
RUNNABLE
sleep
TIMED_WAITING
TIMED_WAITING
TIMED_WAITING
run
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
TERMINATED
能够看出,线程创立后,初始状态为NEW;
调用start办法后状态变更为了RUNNABLE;
当线程内执行了sleep,休眠2秒钟,状态变更为了TIMED_WAITING;
当线程执行实现后,状态变更为了TERMINATED。
示例二:
本示例演示在多线程争抢锁的状况下,线程状态的变动。
private static Object lock = new Object();
public static void main(String[] args) {
Runnable runnable = () -> {
// 加锁
synchronized (lock) {
System.out.println(Thread.currentThread().getName() + " lock");
ThreadUtil.sleep(2000);
}
System.out.println(Thread.currentThread().getName() + " exit");
};
Thread t1 = new Thread(runnable, "t1");
Thread t2 = new Thread(runnable, "t2");
t1.start();
t2.start();
while (true) {
ThreadUtil.sleep(500);
System.out.println(t1.getName() + ":" + t1.getState());
System.out.println(t2.getName() + ":" + t2.getState());
}
}
输入:
t1 lock t1取得了锁
t1:TIMED_WAITING t1 sleep,进入无限期待状态
t2:BLOCKED t2未取得锁,因而进入阻塞状态
t1:TIMED_WAITING
t2:BLOCKED
t1:TIMED_WAITING
t2:BLOCKED
t1 exit t1开释锁,执行实现,退出
t2 lock t2取得锁
t1:TERMINATED t1曾经是退出状态
t2:TIMED_WAITING t2 sleep,进入无限期待状态
t1:TERMINATED
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t1:TERMINATED
t2:TIMED_WAITING
t2 exit t2开释锁,执行实现,退出
t1:TERMINATED t1为退出状态
t2:TERMINATED t2为退出状态
示例三:
本示例演示了线程如何进入和退出WAITING状态。
private static Object obj = new Object();
public static void main(String[] args) {
Runnable runnable = () -> {
synchronized (obj) {
try {
// 期待
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("exit");
}
};
Thread t1 = new Thread(runnable, "t1");
System.out.println(t1.getName() + ":" + t1.getState());
t1.start();
System.out.println(t1.getName() + ":" + t1.getState());
for (int i = 0; i < 20; i++) {
ThreadUtil.sleep(500);
if(i == 3) {
synchronized (obj) {
// 唤醒
obj.notify();
}
}
System.out.println(t1.getName() + ":" + t1.getState());
}
}
输入:
t1:NEW
t1:RUNNABLE
t1:WAITING 调用了obj.wait()进入有限期待状态
t1:WAITING
t1:WAITING
t1:BLOCKED 主线程取得锁,进行notify,t1进入了阻塞状态
exit t1线程退出同步块,执行实现
t1:TERMINATED t1线程退出
t1:TERMINATED
Java Thread的threadStatus字段值的更新代码位于hotspot c++源码中,JDK源码中看不到。
Java的线程状态并非是操作系统的理论线程状态,但与操作系统的线程状态是有对应关系的,后续有须要深入分析操作系统原理、hotspot源码再开展。
发表回复