java线程的生命周期

当线程被创建并启动之后,它既不是一启动就进入执行状态,也不是一直处于执行状态,在其生命周期中,要经过“新建(New)”、“就绪(Runnable)”、“运行(Running')”、“阻塞(Blocked)”和“死亡(Dead)”五种状态。线程在创建之后,不可能一直霸占着CPU独立运行,需要在多个线程之间切换,所以大部分时间处于运行、阻塞之间切换。

一、新建和就绪状态

(1)、当用new关键字创建一个线程的时候,该线程就处于新建状态;

(2)、调用start()方法之后,线程就进入了就绪状态。当不能立刻进入运行状态,要等待JVM里线程调度器的调度。

注意:只能对处于新建状态的线程调用start()方法,否则会引发异常。

二、运行和阻塞状态

(1)、如果处于就绪状态的线程获得了CPU,就开始执行run方法,处于了运行状态。当分配的时间用完后,又进入了就绪状态,等待下次分配到CPU在进入运行状态。

(2)、遇到以下几种情况,线程会进入阻塞状态:

1)、线程调用sleep()方法主动放弃所占用的处理器资源

2)、线程调用了一个阻塞式IO方法,在该方法返回之时,该线程被阻塞

3)、线程试图获得一个同步监视器,但该同步监视器正被其他线程所持有。

4)、现成在等待某个通知(notify)

5)、线程调用了线程的suspend()方法将该线程挂起。该方法容易造成死锁,应尽量避免使用该方法。

进入阻塞状态的程序遇到以下情况才能恢复进入就绪状态,等待分配到资源进入运行状态:

1)、调用sleep()方法的线程经过了指定时间。

2)、线程调用的阻塞式IO方法已经返回

3)、线程成功的获得了试图取得的同步监视器

4)、线程正在等待的某个通知时,其他线程发出了一个通知(signal)

5)、处于挂起状态的线程被调用了resume()恢复方法

三、线程死亡

(1)、run()或call()方法执行完成,线程正常结束;

(2)、线程抛出一个未捕获的Exception或Error;

(3)、直接调用该线程的stop()方法来结束该线程———该方法容易导致死锁,不推荐。

注意:当主线程结束时,其他线程不收任何影响,并不会随之结束。一旦子线程启动起来后,他就拥有和主线程相同的地位,他不会受主线程的影响。

为了测试某个线程是否已经死亡,可以调用线程对象的isAlive方法,当线程处于就绪、运行、阻塞3中状态是,该方法返回true;当线程处于新建、死亡2种状态时,该方法将返回false。

注意:不要试图对一个已经死亡的线程调用start()方法使它重新启动,该线程不可再次作为线程执行。start方法只能对处于新建状态的线程多使用,且只能使用一次!

出处:http://blog.youkuaiyun.com/cl05300629/article/details/12999399作者:伫望碧落

<think>好的,用户想了解Java线程生命周期。我得先回忆一下线程的几个状态,然后按照Java的版本变化来梳理清楚。首先,线程生命周期Java的不同版本中可能有所不同,特别是在Java 5之后引入了新的状态,比如TIMED_WAITING。 我记得线程的状态定义在Thread类的内部枚举State里,包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。需要确认每个状态之间的转换条件,比如线程如何从NEW到RUNNABLE,或者从RUNNABLE到BLOCKED等。 接下来要考虑用户可能的背景。他们可能是刚开始学习多线程的开发者,或者是遇到线程状态相关的问题需要调试。因此,解释需要清晰,结构分明,可能还需要举例说明每个状态对应的场景。 需要确保覆盖所有状态,并正确描述触发状态转换的方法,比如start()、wait()、join()、sleep()等。同要注意区分BLOCKED和WAITING状态的不同,因为这是常见的混淆点。BLOCKED通常是因为等待获取监视器锁,而WAITING是主动调用了等待方法。 另外,要考虑用户可能对状态转换图感兴趣,但无法在这里画图,所以需要用文字描述各个转换路径。比如,当线程调用Object.wait()会进入WAITING,而带有超的等待则进入TIMED_WAITING。 还要检查是否有最新的Java版本引入了新的状态,目前到Java 17为止,State枚举还是那六个状态,没有变化。需要确保信息准确,避免过的内容。 最后,组织回答的结构,先概述生命周期中的各个状态,再逐一详细解释每个状态的定义和触发条件,最后总结状态转换的流程。这样用户能够逐步理解线程在不同阶段的行为,以及如何通过代码控制线程状态的变化。</think>Java线程生命周期线程从创建到销毁的过程,包含6个明确的状态。以下是详细说明: --- ### **1. NEW(新建)** - **定义**:通过`new Thread()`实例化后,尚未调用`start()`方法 - **特征**$$ \text{Thread thread = new Thread();} $$ 此线程对象已创建,但未分配系统资源 --- ### **2. RUNNABLE(可运行)** - **触发条件**:调用`start()`方法后 - **包含两个子状态**: - **Ready**:等待CPU间片 - **Running**:正在执行`run()`方法 - **注意**:此状态对应操作系统层面的"就绪"和"运行中" --- ### **3. BLOCKED(阻塞)** - **触发条件**: - 等待进入`synchronized`同步代码块/方法 - 等待其他线程释放对象锁 - **退出条件**:成功获取对象监视器(锁) --- ### **4. WAITING(无限等待)** - **触发方法**: ```java Object.wait() // 无参 Thread.join() // 无参 LockSupport.park() ``` - **特征**:需要其他线程显式唤醒 $$ \text{notify()/notifyAll()} \Rightarrow \text{WAITING} \rightarrow \text{RUNNABLE} $$ --- ### **5. TIMED_WAITING(限期等待)** - **触发方法**: ```java Thread.sleep(long) Object.wait(long) Thread.join(long) LockSupport.parkNanos(long) ``` - **特征**:设定超间后自动恢复 $$ \text{自动恢复间} = \text{MAX}( \text{参数值}, \text{系统钟精度} ) $$ --- ### **6. TERMINATED(终止)** - **触发条件**: - `run()`方法正常执行结束 - 线程抛出未捕获异常 - **特征**:线程对象仍存在,但不能再调用`start()` --- ### **状态转换流程** ``` NEW → start() → RUNNABLE RUNNABLE → 同步锁竞争 → BLOCKED RUNNABLE → wait()/join() → WAITING RUNNABLE → sleep(n)/wait(n) → TIMED_WAITING 上述状态 → 条件达成 → RUNNABLE 任何状态 → run()结束 → TERMINATED ``` --- ### **验证方法** 通过`Thread.getState()`可获取当前状态: ```java Thread thread = new Thread(() -> { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }); System.out.println(thread.getState()); // 输出 NEW thread.start(); System.out.println(thread.getState()); // 输出 RUNNABLE 或 TIMED_WAITING ``` 理解线程状态对调试多线程程序至关重要,建议结合`jstack`工具分析实际运行线程状态。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值