线程生命周期和线程状态 - 1

“嗨,阿米戈!”

“我们要开始一个新话题:线程。”

“让我们开始吧,今天我们将研究线程运行时Thread对象经过(或可能经过)的状态。”

“阿米戈,你现在能说出多少个州?”

“两个。第一个是调用 start() 方法之前的线程:对象存在,但线程尚未激活。第二个是调用 start() 方法之后:当线程正在做某事时重要的。”

“你说得对——有这样的区别。这些状态被称为newrunning,但这只是开始。”

“首先,在某个时刻线程将结束运行,这意味着可能存在Thread对象存在,但线程不处于新建或运行状态的情况。”线程结束运行的这种状态称为终止了。”

“但还有更多。不要忘记在任何给定时间实际上只有一个线程在运行。看起来同时工作的实际上是处理器不断地从一个线程跳到另一个线程。当线程似乎是running,但实际上是在等待轮到它:它被称为ready-to-run 。作为一个线程工作,它不断地从running切换到ready,然后在它再次激活时返回到running 。

“调用start () 方法后,线程立即被分配到准备运行状态,并放置在 JVM 切换的共享线程列表中。”

” 那也不太难,在它开始运行之前,它有新的状态。它运行完之后,它就终止了。当它运行时,线程处于运行状态;然后在等待时,它处于就绪状态”

“你的简洁是惊人的,但你是对的。”

”但是还有更多。线程可以被阻塞。例如,当您进入同步块时。如果一个线程到达标记为同步的代码块并且另一个线程正在使用它,那么我们的线程将进入阻塞状态并等待用于释放对象的互斥锁(锁)。”

“这是各州的情况:”

线程生命周期和线程状态 - 2

“但还有更多。还有一个单独的状态,叫做等待。这是当一个线程没有被阻塞,但也没有准备好的时候。例如,当你在另一个线程上调用join () 方法时。”

当我们在另一个 Thread 对象上调用 join() 时,就好像我们的线程“加入”了它,但实际上它只是在等待另一个线程完成。

“此外,还有wait () 方法(来自 wait/notify/notifyAll 三重奏方法),它会在线程被调用时将切换到等待状态。”

“哇哦。”

“等一下!还有更多。例如,线程可以通过调用 sleep 方法进入睡眠状态。为此还有一个单独的状态。它称为 « timed waiting »。 « timed waiting »表示线程正在等待某事一个有限的时间。如果你调用一个带参数的等待方法,比如 wait(timeout) 或 join(timeout),那么线程将进入定时等待状态。”

“这是完整的图表:”

线程生命周期和线程状态 - 3

“嗯,就这些吗?或者还有10个更有趣的状态?”

“现在,就是这样。”

“实际上,你可以只记住第一个图表。它更简单。但第二个更准确。”

“奇怪,网上有很多Thread状态图,而且都不一样。”

“这就是我给你这张图的原因——它是最完整、最正确的。”

“在这个图中,就绪状态和运行状态组合在一个称为 runnable 的块中。你知道为什么吗?”

“没有。我还是第一次见到这样的东西。”

Thread类有一个名为State的内部类,以及一个public State getState()方法。”

例子
public enum State
{
 NEW,
 RUNNABLE,
 BLOCKED,
 WAITING,
 TIMED_WAITING,
 TERMINATED;
}

“你总是可以在Thread对象上调用getState () 方法,并找出它的当前状态。而且,当然,它将是 State 枚举值之一。”

“我明白了。所以,真正的状态在 JVM 内部,但也有一些状态可以使用 State getState() 方法通过 Java 代码访问。”

“我会在什么情况下使用它?”

“很可能,永远不会。”

“但你必须知道线程内部发生了什么。否则,你会遇到很多错误,而且你甚至无法猜出是什么导致了它们。”

“此外,雇主喜欢在面试中询问线程状态。”