Java线程生命周期与线程状态
Java线程生命周期
新建(new)
当你创建一个新线程时,它就是新建状态。它会一直是新建状态,直程序调用了它的start()
方法。
从这个意义上讲,线程是不存的。它只是java编程中的一个内部状态。
运行(Runnable)
当调用start()
方法时,线程就进行了RRUNNABLE
运行状态。此时,执行控制权交由线程调度器去完成执行。线程调度器决定该线程应该被执行,还是应该被保留给其它可运行线程的机会。
线程调度是依赖平台的,多线程程序的行为可能因为不同的java实现而异。
在大多数操作系统中,每个线程都有少量的处理时间,称为时间片,用于执行其任务。一个任务当自己的时间片内就是RUNNING
运行状态,当时间片过期,线程就又变成RUNNABLE
可运行状态,并且操作系统交别一个线程分配给处理器。
操作系统用于确定哪个线程要调度的过程称为线程调度,取决于线程的优先级。
操作系统对JVM隐藏了RUNNABLE
和RUNNING
状态,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/