线程的生命周期

线程具有生命周期,其中包含7种状态,分别为出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态。出生状态就是线程被创建时处于的状态:在用户使用该线程实例调用 start() 方法之前线程都处于出生状态;当用户调用 start() 方法后,线程处于就绪状态(又被称为可执行状态);当线程得到系统资源后就进入运行状态。

线程一旦进入可执行状态,就会在就绪与运行状态之间进行转换,同时也有可能进入等待、休眠、阻塞或死亡状态。当处于运行状态下的线程调用 Thread 类中的 wait() 方法时,该线程便进入等待状态,进入等待状态的线程必须调用 Thread 类中的 notify() 方法才能被唤醒,而调用 notifyAll() 方法可将所有处于等待状态下的线程唤醒;当线程调用 Thread 类中的 sleep() 方法时,则会进入休眠状态。如果一个线程在运行状态下发出输入/输出请求,该线程将进入阻塞状态,在其等待输入/输出结束时线程进入就绪状态,对于阻塞的线程来说,即使系统资源空闲,线程依然不能回到运行状态。当线程的 run() 方法执行完毕时,线程进入死亡状态。

使线程处于不同状态下的方法会在 20.4 节中进行讲解,在此读者只需了解线程的多个状态即可。

图20.4描述了线程生命周期中的各种状态。

虽然多线程看起来像同时执行,但事实上在同一时间点上只有一个线程被执行,只是线程之间切换较快,因此才会使人产生线程是同时进行的假象。在 Windows 操作系统中,系统会为每个线程分配一小段 CPU 时间片,一旦 CPU 时间片结束,系统就会将当前线程换为下一个线程,即使该线程没有结束。

要使线程处于就绪状态,有以下几种方法:

  • 调用 sleep() 方法。

  • 调用 wait() 方法。

  • 等待输入/输出完成。

当线程处于就绪状态后,可以用以下几种方法使线程再次进入运行状态:

  • 线程调用 notify() 方法。

  • 线程调用 notifyAll() 方法。

  • 线程调用 interrupt() 方法。

  • 线程的休眠时间结束。

  • 输入/输出结束。

图20.4中描述了线程的生命周期状态,下面将着重讲解使线程处于各种状态的方法。

image 2024 03 06 11 19 44 700
Figure 1. 图20.4 线程的生命周期状态图