【线程】线程的生命周期和状态
(1)从OS层面,5状态模型
【初始状态】仅是在语言层面创建了线程对象,还未与操作系统线程进行关联
- 相当于我们new Thread(),线程对象已经有了,但是还没有调用其start()
【可运行状态】(就绪状态)指该线程已经被创建(与操作系统线程关联),随时可以由 CPU 调度执行
- 调用线程的start()方法,此线程进入就绪状态。
- 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
- 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
- 锁池里的线程拿到对象锁后,进入就绪状态。
【运行状态】指获取了 CPU 时间片运行中的状态
- 当 CPU 时间片用完,会从【运行状态】转换至【可运行状态】,会导致线程的上下文切换
【阻塞状态】
- 如果调用了阻塞 API,如 BIO 读写文件,这时该线程实际不会用到 CPU,会导致线程上下文切换,进入 【阻塞状态】
- 等 BIO 操作完毕,会由操作系统唤醒阻塞的线程,转换至【可运行状态】
- 与【可运行状态】的区别是,对【阻塞状态】的线程来说只要它们一直不唤醒,调度器就一直不会考虑 调度它们
- 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)时的状态。
- 【终止状态】表示线程已经执行完毕,生命周期已经结束,不会再转换为其它状态
(2)从 Java API 层面来描述的,根据 Thread.State 枚举,分为六种状态
- NEW 新建状态,线程对象刚被创建,但是还没有调用 start() 方法
RUNNABLE 当调用了 start() 方法之后,就会进入Runnable状态。
- 注意,Java API 层面的 RUNNABLE 状态涵盖了 操作系统 层面的 【可运行状态】、【运行状态】和【阻塞状态】
- 这里的阻塞是指:由于 BIO 导致的线程阻塞,在 Java 里无法区分,仍然认为 是可运行
- 就绪状态、运行状态、正在阻塞IO的线程,统统属于Runnable状态
BLOCKED , WAITING , TIMED_WAITING 都是 Java API 层面对OS【阻塞状态】的细分,后面会在状态转换一节 详述
- BLOCKED :对锁资源的等待状态
- WAITING :没有时限的等待状态,如在线程A中,调用B.join(),线程A等待线程B运行结束,那么线程A就陷入了 WAITING 状态
- TIMED_WAITING :有时限的等待状态,sleep(1000),那么线程在这1s内,就是TIMED_WAITING 状态
WAITING、TIMED_WAITING 一般是线程的主动行为;而BLOCKED 一般是被动行为
- TERMINATED 当线程代码运行结束
状态 | 解释 | 说明 |
NEW | 新建一个线程对象,还没有调用start()方法 | new一个线程实例,线程还没有start |
RUNNABLE | Java线程中将就绪(READY)和运行中(RUNNING)两种状态统一为 RUNABLE | 等待被调度或正在运行中 |
BLOCKED | 表示线程阻塞于锁 | 线程阻塞在进入synchronized修饰的方法或代码块时的状态 |
WAITING | 进行该状态的线程需要等待其他线程做出一些特定动作(通知或中断) | 让出CPU,等待被显示的唤醒,被唤醒后进入BLOCKED状态,重新获取锁 |
TIMED_WAITING | 不同于waiting,它可以在指定的时间后自行返回 | 有时限的等待状态,sleep(1000),那么线程在这1s内,就是TIMED_WAITING 状态 |
TERMINATED | 表示显示已经执行完毕 |
代码实例:
package com.java_thread.often_methods;
/**
* 线程状态(Java层面)
*/
public class ThreadState {
public static void main(String[] args) throws InterruptedException {
//1、NEW
Thread t1 = new Thread(() -> {
});
System.out.println(t1.getState());
//2、RUNNING (操作系统层面的可运行、运行、阻塞三者合为RUNNING)
Thread t2 = new Thread(() -> {
while (true) {
}
});
t2.start();
System.out.println(t2.getState());
//3、TERMINATED 已终止
Thread t3 = new Thread(() -> {
});
t3.start();
Thread.sleep(1000);
System.out.println(t3.getState());
//4、TIMED_WAITING 等待终止
Thread t4 = new Thread(() -> {
try {
Thread.sleep(1000*3);
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t4.start();
Thread.sleep(1000);
System.out.println(t4.getState());
//5、WAITING 等待
Thread t5 = new Thread(() -> {
try {
//等待t2线程完成
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t5.start();
Thread.sleep(1000);
System.out.println(t5.getState());
//6、BLOCKED 受阻
//test线程提前拿到锁
Thread test = new Thread(() -> {
synchronized (ThreadState.class) {
try {
Thread.sleep(1000*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
test.start();
Thread t6 = new Thread(() -> {
synchronized (ThreadState.class) {
try {
Thread.sleep(1000*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t6.start();
Thread.sleep(1000);
System.out.println(t6.getState());
}
}
还没有评论,来说两句吧...