Java线程状态介绍与示例——线程的生命周期

已发表: 2019-01-11
Java 线程状态介绍与示例

线程状态

下图说明了 Java 线程在其生命周期中的任何时候可能处于的各种状态,以及哪些方法调用会导致转换到另一个状态。 该图不是一个完整的有限状态图,而是一个线程生命中更有趣和更常见的方面的概述。

如果您有以下任何问题,那么您来对地方了:

  • Java中线程的生命周期
  • Java中线程的生命周期和状态
  • 了解 Java 线程状态

本页的其余部分根据其状态讨论Thread's life cycle

Java 线程状态与示例

新线程

下面的语句创建了一个新线程,但没有启动它,从而使线程处于图中标记为 New Thread 的状态。

当一个线程处于New Thread状态时,它只是一个空的 Thread 对象。 尚未为其分配系统资源。 因此当线程处于这种状态时,只能启动或停止线程; 当线程处于此状态时调用除start()stop()之外的任何其他方法都没有意义,并导致 IllegalThreadStateException。

可运行

现在考虑这两行代码:

start()方法创建运行线程所需的系统资源,调度线程运行,并调用线程的run()方法。 此时线程处于“可运行”状态。 这种状态称为“Runnable”而不是“Running”,因为线程在这种状态下可能实际上并未运行。 许多计算机只有一个处理器,因此不可能同时运行所有“可运行”线程。

因此,Java 运行时系统必须实现一个调度方案,在所有“可运行”线程之间共享处理器。 但是,对于大多数目的,您可以将“可运行”状态简​​单地视为“正在运行”。 当一个线程正在运行时——它是“可运行的”并且是当前线程——它的run()中的指令是按顺序执行的。

不可运行

当以下四个事件之一发生时,线程进入Not Runnable状态:

  • 有人调用它的suspend()方法
  • 有人调用它的sleep()方法
  • 线程使用它的wait()方法等待条件变量
  • 线程在 I/O 上阻塞。

例如,此代码段中的粗体行

使myThread休眠 10 秒(10,000 毫秒)。 在这 10 秒内,即使处理器可用, myThread也不会运行。 10 秒后, myThread再次变为“可运行”,现在如果处理器可用, myThread将运行。

对于上面列出的进入“不可运行”状态的每个“入口”,都有一个特定且不同的逃生路线将线程返回到“可运行”状态。 逃生路线仅适用于其相应的“入口”。 例如,如果一个线程已经进入睡眠状态,那么在线程再次变为“可运行”之前必须经过指定的毫秒数。 在休眠线程上调用resume()无效。

以下指示了进入“不可运行”状态的每个入口的逃生路线。

  • 如果线程已进入睡眠状态,则必须经过指定的毫秒数。
  • 如果一个线程被挂起,那么必须有人调用它的resume()方法。
  • 如果线程正在等待条件变量,则拥有该变量的任何对象都必须通过调用notify()notifyAll()放弃它。
  • 如果线程在 I/O 上被阻塞,则指定的 I/O 命令必须完成。
java线程教程

死的

线程可能以两种方式死亡:自然原因或被杀死(停止)。 当其run()方法正常退出时,线程自然死亡。 例如,该方法中的while循环是一个有限循环——它将迭代 100 次然后退出。

在循环和run()方法完成后,具有此run()方法的线程将自然死亡。

你也可以随时通过调用它的stop()方法来终止一个线程。 此代码片段。

创建并启动myThread然后让当前线程休眠 10 秒。 当当前线程唤醒时,代码段中的粗线将杀死myThread

stop()方法在线程上抛出一个 ThreadDeath 对象来杀死它。 因此,当一个线程以这种方式被杀死时,它会异步死亡。 线程在实际接收到 ThreadDeath 异常时将死亡。

非法线程状态异常

当您调用线程上的方法并且该线程的状态不允许该方法调用时,运行时系统会引发 IllegalThreadStateException。 例如,当您在不是“可运行”的线程上调用suspend()时,会引发 IllegalThreadStateException。

如本课到目前为止的各种线程示例所示,当您调用一个可以抛出异常的线程方法时,您必须要么捕获并处理异常,要么声明调用方法抛出未捕获的异常。

isAlive() 方法

关于线程状态的最后一句话:Thread 类的编程接口包括一个名为isAlive()的方法。 如果线程已启动且未停止,则isAlive()返回 true。 因此,如果isAlive()方法返回false ,您就知道该线程是“新线程”或“死线程”。

如果isAlive()方法返回true ,你就知道线程要么是“Runnable”,要么是“Not Runnable”。 您无法区分“新线程”和“死线程”; 您也无法区分“可运行”线程和“不可运行”线程。

在查看复杂的线程示例时,在网上发现了这个非常棒的教程。 每个人都应该仔细阅读这篇文章。