首页 理论教育 线程状态的变化及线程的活动状态

线程状态的变化及线程的活动状态

时间:2023-11-01 理论教育 版权反馈
【摘要】:当导致阻塞的原因被解除后,线程便从阻塞状态回到就绪状态,等待线程调度器的再次调度。线程调用了某个对象的wait方法后进入阻塞,直到该线程被唤醒进入就绪状态。图6-13使用标志终止线程示例Thread类public final boolean is Alive()方法用于测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

线程状态的变化及线程的活动状态

任何对象都有生命周期,下面对一个线程对象生命周期的5种状态加以说明。

1.新建状态(new)

使用new关键字创建线程对象之后,该线程就处于新建状态,此时仅由JVM为其分配内存并初始化其成员变量的值,此时的线程对象还没有表现出任何线程的动态特征。

2.就绪状态(runnable)

当线程对象调用start方法之后就处于就绪状态,表示该线程具备了运行条件,至于该线程何时能真正开始运行,取决于JVM线程调度器的调度。

3.运行状态(running)

如果处于就绪状态的线程获得了调度,得到CPU使用权,便开始执行run方法中的代码,此时该线程就处于运行状态。一个线程运行后,不会一直处于运行状态,例如,分配的CPU时间到而被中断回到就绪状态、由于等待某种资源而进入阻塞状态、任务完成而进入死亡状态等。

4.阻塞状态(blocked)

一个正在执行的线程会在某些特殊情况下被阻塞而暂停执行,线程从运行状态进入阻塞状态。当导致阻塞的原因被解除后,线程便从阻塞状态回到就绪状态,等待线程调度器的再次调度。例如:

(1)线程执行线程休眠sleep方法后便进入阻塞状态,等指定时间到了后便进入就绪状态。

(2)线程调用线程插队join方法,调用该方法的线程将被阻塞,直到该join()方法加入的线程执行完毕才能解除阻塞。

(3)线程调用了某个对象的wait方法后进入阻塞,直到该线程被唤醒进入就绪状态。

(4)线程试图获取某个对象的同步锁,而该锁被其他线程持有,则当前线程会进入阻塞状态,直到获取到该锁后进入就绪状态。

(5)线程执行I/O流操作,会进入阻塞状态,直到导致阻塞的I/O方法返回。

5.死亡状态(terminated)

死亡状态是线程生命周期中的最后一个阶段,一旦进入死亡状态,便不能再回到其他状态。线程进入死亡状态有如下原因:

(1)run方法执行完成,线程正常结束。(www.xing528.com)

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

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

如何终止Java线程是我们开发多线程程序时面对的一个问题。除了使用不推荐的stop方法外,我们还可以使用interrupt方法让线程在run方法中停止,或者当run方法中存在死循环时,通过设置退出标志,使run执行后线程正常终止。

本节只讲解使用标志控制的场景。我们知道,当线程的run方法执行完毕后,线程就会正常终止退出。但是,有的线程的run方法如果不干涉的话永远不会结束。例如,服务器端使用线程监听客户端请求的任务,或者其他需要不断循环处理的任务。为了使一个循环在某特定条件下退出,常用的一种方法就是提供一个boolean型的标志,通过控制这个标志来控制是否退出循环,从而终止线程。

【例6-5】

使用退出标志终止一个线程。

步骤1:在项目chapter6的src目录下新建cn.linaw.chapter6.demo03包,在包下定义一个服务器端任务Server Task类,如图6-12所示。

图6-12 服务器端任务Server Task类

在Server Task类中,提供了一个成员变量flag,初始化为true。在run方法体中,根据flag变量的取值控制循环是否退出。

步骤2:通过一个测试用例Thread TerminateTest类来演示如何终止一个处于活动状态的线程,如图6-13所示。

图6-13 使用标志终止线程示例

(1)Thread类public final boolean is Alive()方法用于测试线程是否处于活动状态。如果线程已经启动且尚未终止,则为活动状态。

(2)注意main线程中两次sleep方法的作用。

(3)图6-13中控制台Console输出只截取了最后几次打印结果。线程在被终止前执行了很多次循环。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈