线程的生命周期
线程生命周期指的是一个线程从被创建到运行到结束的整个过程。一般来说,线程生命周期包括以下几个阶段:
-
新建状态(New):当一个线程被创建时,它处于新建状态。此时系统分配了线程所需的资源,但线程还没有开始运行。
-
就绪状态(Runnable):当线程的 start() 方法被调用时,线程进入就绪状态。此时线程已经准备好了运行,但还没有分配到 CPU 资源。
-
运行状态(Running):当线程获得了 CPU 资源,它就进入运行状态。此时线程开始执行自己的代码,直到遇到阻塞、等待或者被中断等情况。
-
阻塞状态(Blocked):当线程需要等待某个事件发生时,它会进入阻塞状态。例如,当调用 Thread.sleep() 方法或者等待 I/O 完成时,线程就会进入阻塞状态。
-
等待状态(Waiting):当线程等待某个条件满足时,它会进入等待状态。例如,调用 Object.wait() 方法时,线程会等待其他线程调用 notify() 或者 notifyAll() 方法来唤醒它。
-
定时等待状态(Timed Waiting):和等待状态类似,但是可以设置等待的时间。例如,调用 Thread.sleep() 或者带有超时参数的 Object.wait() 方法时,线程会进入定时等待状态。
-
终止状态(Terminated):当线程执行完毕或者出现异常时,它就进入终止状态。
下面是一个简单的示例程序,演示线程的生命周期:
public class ThreadLifecycleDemo {
public static void main(String[] args) {
// 创建线程对象
Thread thread = new Thread(() -> {
System.out.println("线程开始执行");
try {
Thread.sleep(1000); // 线程进入定时等待状态
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程执行完毕");
});
// 打印线程状态
System.out.println("线程当前状态:" + thread.getState());
// 启动线程
thread.start();
// 等待线程执行完毕
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
// 打印线程状态
System.out.println("线程当前状态:" + thread.getState());
}
}
输出结果如下:
线程当前状态:NEW
线程开始执行
线程执行完毕
线程当前状态:TERMINATED
可以看到,线程会依次进入新建状态、就绪状态、运行状态、定时等待状态和终止状态。在示例程序中,我们使用 join() 方法等待线程执行完毕后再打印线程状态,这样可以确保我们看到的状态是最终状态。
小故事
有一个小故事叫做“小明和他的线程”,它可以帮助我们了解线程的生命周期。
小明是一位程序员,他正在开发一个在线游戏。在游戏中,他需要有一个线程来处理用户的输入。所以,他创建了一个线程,并给它取名叫“输入处理线程”。
第一阶段:创建(New)
当小明创建了输入处理线程,线程就进入了创建阶段。在这个阶段,操作系统为线程分配了必要的资源,例如内存和CPU时间。
第二阶段:就绪(Runnable)
一旦输入处理线程被分配了必要的资源,它就可以进入就绪状态。在就绪状态中,线程准备好运行,但是它还没有被调度为运行状态。此时,操作系统会把线程放到就绪队列中,等待CPU的调度。
第三阶段:运行(Running)
当操作系统将输入处理线程从就绪队列中调度出来,并分配了CPU时间,线程就可以进入运行状态。在运行状态中,线程会执行它的任务,例如处理用户输入。
第四阶段:阻塞(Blocked)
有时候,线程执行任务时会被阻塞,例如等待一个网络请求或者等待一个锁。在这种情况下,线程会进入阻塞状态,直到它的任务可以继续执行。
第五阶段:终止(Terminated)
当线程完成了它的任务或者发生了一个致命错误,线程就会进入终止状态。在终止状态中,线程释放了它所占用的资源,并且不再运行。
在小明的例子中,当输入处理线程完成了处理用户输入的任务,它就会进入终止状态。然后,小明可以重新创建一个新的线程来处理下一个用户输入。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?