Java一个线程的生命周期详解

本文涉及的产品
实时计算 Flink 版,5000CU*H 3个月
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
实时数仓Hologres,5000CU*H 100GB 3个月
简介: Java中,一个线程的生命周期分为五个阶段:NEW(新建),RUNNABLE(可运行),BLOCKED(阻塞),WAITING(等待),TERMINATED(终止)。线程创建后处于新建状态,调用start方法进入可运行状态,执行中可能因等待资源进入阻塞或等待状态,正常完成或异常终止后进入终止状态。各状态间可相互转换,构成线程的生命周期。

Java 线程生命周期是指线程从创建到终止的整个过程。一个线程的生命周期可以分为多个状态,每个状态之间可以根据特定事件进行转换。以下是线程生命周期的详细介绍:

1. 线程的状态

Java 中线程的状态主要有以下几种:

  • 新建 (New):线程被创建后,处于新建状态。在这个状态下,线程对象已经被创建,但是尚未开始执行。

  • Runnable (就绪):线程在新建状态后调用 start() 方法进入 Runnable 状态。这个状态表示线程已经准备好运行,但并不一定正在运行;它可能会因为 CPU 的调度而被挂起。Runnable 状态实际上包括了所有准备要执行以及正在执行的线程。

  • Blocked (阻塞):当一个线程试图获取一个已经被其他线程持有的对象锁时,它会进入阻塞状态。此时,该线程无法继续执行,直到获得该锁。

  • Waiting (等待):处于等待状态的线程是在等待某个条件的发生,通常是通过调用 Object.wait()Thread.join()LockSupport.park() 等方法。线程在这个状态不能被调度。

  • Timed Waiting (计时等待):与等待状态类似,但在计时等待状态下,线程在一定的时间后会自动返回 Runnable 状态。常见的调用方法包括 Thread.sleep(millis)Object.wait(millis)Thread.join(millis)LockSupport.parkNanos()

  • Terminated (死亡):线程完成执行或由于异常结束后进入终止状态。在这个状态下,线程对象仍然存在,但无法重新启动。

2. 状态转换过程

以下是线程在不同状态之间的转换过程:

  1. 新建到 Runnable:线程通过调用 start() 方法转换为 Runnable 状态。
  2. Runnable 到 Running:当线程获得 CPU 时间片时,转换为 Running 状态。
  3. Running 到 Blocked:如果线程试图获取一个被其他线程持有的锁,它将进入 Blocked 状态。
  4. Running 到 Waiting:当线程调用 Object.wait()Thread.join() 等方法后,将进入 Waiting 状态。
  5. Running 到 Timed Waiting:调用 Thread.sleep(millis)Object.wait(millis) 后,将进入 Timed Waiting 状态。
  6. Waiting 到 Runnable:当满足条件后(如调用 notify()notifyAll()),线程将转回 Runnable 状态。
  7. Blocked 到 Runnable:当持有锁的线程释放锁后,阻塞的线程将转换为 Runnable 状态。
  8. 任何状态到 Terminated:当线程的 run() 方法执行完毕或抛出未捕获的异常时,线程进入 Terminated 状态。

3. 线程状态图

以下是 Java 线程状态的简化状态图示意:

          +-------+
          |  New  |----->  +--------+
          +-------+        | Runnable|
                          +--------+
                               |   ^
                               v   |
                           +-----------+
                           |  Running  |
                           +-----------+
                               | | |
               +---+          | | |
               |   |          | | |
               v   v          | | |
          +--------+         +--------+
          | Blocked |         | Waiting |
          +--------+         +--------+
               ^                ^
               |                |
               +----------------+

4. 例子

下面的代码片段展示了如何创建一个线程,以及它的生命周期中的状态转换:

class MyThread extends Thread {
   
    public void run() {
   
        try {
   
            System.out.println(Thread.currentThread().getName() + " is running.");
            Thread.sleep(1000); // Timed Waiting 状态
            System.out.println(Thread.currentThread().getName() + " is resumed.");
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

public class ThreadLifecycleExample {
   
    public static void main(String[] args) {
   
        MyThread thread = new MyThread(); // New 状态
        thread.start(); // 变为 Runnable 状态
    }
}

5. 总结

理解 Java 线程的生命周期对于开发并发程序非常重要。线程的状态决定了线程的执行行为和调度策略,对于实现复杂的多线程应用至关重要。合理使用线程的状态转换,有助于提高程序的性能和响应能力。

相关文章
|
1天前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
[Java]线程生命周期与线程通信
|
3天前
|
Java API 调度
Java中的多线程编程:理解与实践
本文旨在为读者提供对Java多线程编程的深入理解,包括其基本概念、实现方式以及常见问题的解决方案。通过阅读本文,读者将能够掌握Java多线程编程的核心知识,提高自己在并发编程方面的技能。
|
1天前
|
Java
Java中的多线程编程:从入门到精通
本文将带你深入了解Java中的多线程编程。我们将从基础概念开始,逐步深入探讨线程的创建、启动、同步和通信等关键知识点。通过阅读本文,你将能够掌握Java多线程编程的基本技能,为进一步学习和应用打下坚实的基础。
|
2天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
10 3
|
2天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
8 2
|
2天前
|
Java
在Java多线程编程中,实现Runnable接口通常优于继承Thread类
【10月更文挑战第20天】在Java多线程编程中,实现Runnable接口通常优于继承Thread类。原因包括:1) Java只支持单继承,实现接口不受此限制;2) Runnable接口便于代码复用和线程池管理;3) 分离任务与线程,提高灵活性。因此,实现Runnable接口是更佳选择。
10 2
|
2天前
|
Java
Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口
【10月更文挑战第20天】《JAVA多线程深度解析:线程的创建之路》介绍了Java中多线程编程的基本概念和创建线程的两种主要方式:继承Thread类和实现Runnable接口。文章详细讲解了每种方式的实现方法、优缺点及适用场景,帮助读者更好地理解和掌握多线程编程技术,为复杂任务的高效处理奠定基础。
10 2
|
2天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
8 1
|
2天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
12 1
|
2天前
|
Java
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅。它们用于线程间通信,使线程能够协作完成任务。通过这些方法,生产者和消费者线程可以高效地管理共享资源,确保程序的有序运行。正确使用这些方法需要遵循同步规则,避免虚假唤醒等问题。示例代码展示了如何在生产者-消费者模型中使用`wait()`和`notify()`。
8 1