首页 理论教育 线程的生命周期

线程的生命周期

时间:2022-02-28 理论教育 版权反馈
【摘要】:一个线程通过new()方法创建之后,总是处于其生命周期的4个状态之一。线程的状态表明此线程当前正在进行的活动,而线程的状态是可以通过Thread类中的方法来进行控制的,就是说,可以对线程进行操作来改变状态。处于创建状态的线程还没有获得应有的资源,因此这是一个空线程。退让操作是使某个线程把CPU控制权提前转交给同级优先权的其他线程。比如,对由于阻塞而进入不可运行状态的线程采用恢复操作将是无效的。

11.3.1 线程的生命周期

线程像生命体一样存在生老病死,它具备4种不同的状态,创建(new)、可运行(runable)、不可运行(not runable)和消亡(dead),线程的生命周期如图11-3所示。

一个线程通过new()方法创建之后,总是处于其生命周期的4个状态之一。线程的状态表明此线程当前正在进行的活动,而线程的状态是可以通过Thread类中的方法来进行控制的,就是说,可以对线程进行操作来改变状态。这些操作包括启动(start)、终止(stop)、睡眠(sleep)、挂起(suspend)、恢复(resume)、等待(wait)和通知(notify)。每一个操作都对应了一个方法,这些方法是由软件包java.lang提供的。

img650

图11-3 线程状态调度图

1.创建(new)状态

如果创建了一个线程而没有启动它,那么该线程就处于创建状态。比如下述语句执行以后,使系统有了一个处于创建状态的线程myThread:

Thread myThread=new MyThreadClass();其中,MyThreadClass()是Thread的子类,而Thread是由Java系统的java.lang软件包提供的。

处于创建状态的线程还没有获得应有的资源,因此这是一个空线程。线程只有启动后,系统才会为它分配资源。对处于创建状态的线程可以进行两种操作:①启动(start)操作,使其进入可运行状态;②终止(stop)操作,使其进入消亡状态。如果进入到消亡状态,此后这个线程就不能进入其他状态,即它不再存在了。

start()方法是对应启动操作的方法,其具体功能是为线程分配必要的系统资源,将线程设置为可运行状态,使系统可调度这个线程。

2.可运行(Runnable)状态

当一个线程被启动,则它便进入可运行状态,用下列语句:myThread.start();则线程myThread进入可运行状态。上述语句实质上是调用了线程体,即run()方法。线程处于可运行状态只说明它具备了运行条件,但可运行状态并不一定是运行状态。因为在单处理器系统中运行多线程程序,实际上在一个时间点只有一个线程在运行,而系统中往往有多个线程同时处于可运行状态。系统通过快速切换和调度使所有可运行线程共享处理器,造成宏观上的多线程并发运行。

可见,一个线程是否处于运行状态,除了必须处于可运行状态外,还取决于系统的调度。在可运行状态可以进行多种操作,最通常的是从run()方法正常退出而使线程结束,进入消亡状态。此外,还可以有如下操作:

·挂起操作,通过调用suspend()方法来实现;

·睡眠操作,通过调用sleep()方法来实现;

·等待操作,通过调用wait()方法来实现;

·退让操作,通过调用yield()方法来实现;

·终止操作,通过调用stop()方法来实现。

前面3种操作都会使一个处于可运行状态的线程进入不可运行状态。例如,仍以myThread线程为例,当其处于可运行状态后,再用如下语句:

myThread.sleep(5000);

则调用sleep方法使myThread线程睡眠5秒(5 000毫秒)。期间此线程不能被系统调度运行,5秒后,myThread线程才会醒来并自动回到可运行状态。如果一个线程被执行挂起操作而转到不可运行状态,则必须通过调用恢复(resume)操作,才能使这个线程再回到可运行状态。退让操作是使某个线程把CPU控制权提前转交给同级优先权的其他线程。对可运行状态的线程也可以通过调用stop方法使其进入消亡状态。

3.不可运行(not Runable)状态

不可运行状态都是由可运行状态转变来的。一个处于可运行状态的线程,如果遇到挂起(suspend)操作、睡眠(sleep)操作或者等待(wait)操作,就会进入不可运行状态。另外,如果一个线程是和I/O操作有关的,当执行I/O指令时,由于外设速度远远低于处理器速度而使线程受到阻塞,从而进入不可运行状态,只有外设完成输入/输出之后,该线程才会自动回到可运行状态。线程进入不可运行状态后,还可以再回到可运行状态。通常有如下3种途径使其恢复到可运行状态。

①自动恢复,通过睡眠(sleep)操作而进入不可运行状态的线程会在过了指定睡眠时间以后自动恢复到可运行状态;由于I/O阻塞而进入不可运行状态的线程在外设完成I/O操作后,自动恢复到可运行状态。

②用恢复(resume)方法使其恢复,如果一个线程由于挂起(suspend)操作而从可运行状态进入不可运行状态,那么,必须用恢复(resume)操作使其再恢复到可运行状态。

③用通知(notify或notifyAll)方法使其恢复,如果一个处于可运行状态的线程由于等待(wait)操作而转入不可运行状态,那么,必须通过调用notify方法或notifyAll方法才能使其恢复到可运行状态。采用等待操作往往是由于线程需要等待某个条件变量,当获得此条件变量后,便可由notify或notifyAll方法使线程恢复到可运行状态。

恢复到可运行状态的每一种途径都是有针对性的,不能交叉。比如,对由于阻塞而进入不可运行状态的线程采用恢复操作将是无效的。在不可运行状态,也可由终止(stop)操作使其进入消亡状态。

4.消亡(dead)状态

一个线程可以由其他任何一个状态通过终止(stop)操作而进入消亡状态。线程一旦进入消亡状态,那它就不再存在,所以不可能再转到其他状态。

通常,在一个应用程序运行时,如果通过其他外部命令终止当前应用程序,那么就会调用stop方法终止线程。但是,最正常、最常见的途径是由于线程在可运行状态正常完成自身的任务而“寿终正寝”,从而进入消亡状态,这个完成任务的动作是由stop方法实现的。

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

我要反馈