Java线程生命周期与线程状态

Java线程生命周期

新建(new)

当你创建一个新线程时,它就是新建状态。它会一直是新建状态,直程序调用了它的start()方法。
从这个意义上讲,线程是不存的。它只是java编程中的一个内部状态。

运行(Runnable)

当调用start()方法时,线程就进行了RRUNNABLE运行状态。此时,执行控制权交由线程调度器去完成执行。线程调度器决定该线程应该被执行,还是应该被保留给其它可运行线程的机会。
线程调度是依赖平台的,多线程程序的行为可能因为不同的java实现而异。
在大多数操作系统中,每个线程都有少量的处理时间,称为时间片,用于执行其任务。一个任务当自己的时间片内就是RUNNING运行状态,当时间片过期,线程就又变成RUNNABLE可运行状态,并且操作系统交别一个线程分配给处理器。
操作系统用于确定哪个线程要调度的过程称为线程调度,取决于线程的优先级。

操作系统对JVM隐藏了RUNNABLERUNNING状态,JVM只能看到RUNNABLE状态

阻塞(Blocked)

RUNNABLE线程尝试执行无法立即完成的任务时,会转化到阻塞状态,并且必须暂时等待该任务完成。

例如,当线程发出输入、输出请求时,操作系统将阻塞线程执行,直到该输入输出请求完成为止,此时阻塞的线程将转换到RUNNABLE状态,恢复执行。 被阻塞的线程不能使用处理器,即使有可用的处理器。

等待(Waiting)

一个线程可能由于多种原因进行等待状态,比如调用它的wait()方法。通常因为在当前线程执行前还需要做其它事情,就会把当前线程置于WAIT状态。
线程等待状态结束后,状态前变更为RUNNABLE,并将其移回线程池。

计时等待(Timed Waiting)

如果RUNANBLE线程在等待另一个线程执行任务时提供可选的等待间隔,则RUNNABLE线程可以转换到TIMED WAITING状态。你可以通过调用它的sleep(long millis)方法或wait(long millis)方法把一个java线程置于TIMED WAITING状态。

当一个线程被另一个线程通知或定时间隔到期时(以先到者为准)返回到RUNNABLE状态。

定时等待的线程不能使用处理器,即使有可用的处理器。

终止(Terminated)

当线程成功完成任务或由于任何错误而被终止或甚至被强行杀死时,线程进入TERMINATED状态(有时称为死状态)。

与操作系统原理中的对比

在《计算机操作系统》中的第二章,进程管理中,介绍了进程的三种基本状态:

  • 就绪
  • 执行
  • 阻塞

就绪 -> 执行 : 进程调度
执行 -> 就绪 : 时间片完
执行 -> 阻塞 : I/O 请求
阻塞 -> 就绪 : I/O 完成

与这里讲的java线程状态有很多不同。

  • 一个讲的是线程,一个讲的是进程。
  • 操作系统讲行更是通用的情况
  • 这里讲的是java的具体的情况
  • 在线程调度中阻塞要进入就绪状态后,才能进行执行状态。
  • java线程介绍中隐去了操作系统中的状态,抽象层次更高。

参考

https://docs.oracle.com/javase/6/docs/api/java/lang/Thread.State.html
http://howtodoinjava.com/core-java/multi-threading/java-thread-life-cycle-and-thread-states/