线程的生命周期
线程在Java中有以下几种状态:
- 新建(New):初始化状态
- 就绪(Runnable):可运行、运行状态
- 阻塞(Blocked):等待状态,无时限
- 等待(Waiting):等待状态,有时限
- 超时等待(Timed Waiting):就绪状态
- 终止(Terminated):终止状态
线程状态枚举代码
public static enum State {
NEW,
RUNNABLE,
BLOCKED,
WAITING,
TIMED_WAITING,
TERMINATED;
private State() {
}
}
线程的状态流转图
线程各个状态说明
新建(New):当线程对象被创建但还没有调用start()方法时,线程处于新建状态。
就绪(Runnable):一旦线程调用了start()方法,它进入就绪状态。线程处于就绪状态时,表示它已经准备好被JVM调度执行,只是还没有得到CPU的时间片。
- 就绪状态只是说你自个儿运行,调度程序没有挑选到你,你就永远是就绪状态。
- 调用线程的start()方法,此线程进入就绪状态。
- 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
- 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
- 锁池里的线程拿到对象锁后,进入就绪状态。
运行(Running):当线程获得CPU时间片并开始执行时,它进入运行状态。
阻塞(Blocked):线程因为某些原因放弃CPU使用权,暂时停止运行,进入阻塞状态。比如线程在等待某个资源,或者调用了sleep()、wait()等方法。
- 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)之前时的状态。
等待(Waiting):线程进入等待状态,表示它正在等待其他线程做出一些特定动作(通常是通知或中断)。
- 调用sleep或是wait方法后线程处于WAITING状态,等待被唤醒。
超时等待(Timed Waiting):线程在等待指定的时间后会自动转为就绪状态。
- 调用sleep或是wait方法后线程处于TIMED_WAITING状态,等待被唤醒或时间超时自动唤醒。
终止(Terminated):线程执行完任务后或者因异常退出了run()方法,进入终止状态。
- 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
- 在一个终止的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
线程状态之间的转换
NEW到RUNNABLE 状态
线程从NEW状态到RUNNABLE状态的转换通常发生在调用start()方法后。当线程对象被创建时,处于NEW状态,一旦调用start()方法,线程就会进入就绪(RUNNABLE)状态。在就绪状态下,表示线程已经准备好被JVM调度执行,只是还没有得到CPU的时间片。一旦获得CPU时间片,线程就会进入运行状态,开始执行其对应的run()方法中的代码。
RUNNABLE与BLOCKED 的状态转换
线程从RUNNABLE状态到BLOCKED状态的转换通常发生在线程等待获取某个锁资源时。当一个线程在运行过程中,需要访问一个被其他线程持有的锁时,它会进入BLOCKED状态。这可能是因为其他线程已经获取了该锁,并且当前线程需要等待其他线程释放锁才能继续执行。
具体来说,当一个线程在尝试获取一个锁时,如果锁已经被其他线程持有,那么当前线程将由RUNNABLE状态转换为BLOCKED状态。一旦其他线程释放了锁,当前线程将重新进入就绪状态,等待系统分配CPU资源,然后再次尝试获取锁并进入运行状态。
这种状态转换通常涉及多线程的并发操作,开发者需要合理地设计和管理锁资源,以避免线程因争夺锁而频繁进入BLOCKED状态,影响程序的性能和并发效率
RUNNABLE与WAITING 的状态转换
线程从RUNNABLE状态到WAITING状态的转换通常发生在调用了Object类的wait()方法或Thread类的join()方法时。
当一个线程调用了Object类的wait()方法后,该线程会释放占有的锁并进入WAITING状态,等待其他线程通过notify()或notifyAll()方法来唤醒它。在WAITING状态下,线程不会争夺CPU资源,只有当其他线程显式地唤醒它后,才有机会重新进入就绪状态。
另外,当一个线程调用了Thread类的join()方法后,它会等待被调用线程执行完毕。在调用线程的join()方法后,调用线程会进入WAITING状态,直到被调用线程执行完毕才会重新进入就绪状态。
需要注意的是,线程从WAITING状态到RUNNABLE状态的转换是由其他线程显式地唤醒或被调用线程执行完毕触发的,而不是自动发生的。这种状态转换多用于线程间的协作和同步操作,通过合理地使用wait()、notify()、join()等方法可以实现线程间的通信和协调。
RUNNABLE到TIMED TERMINATED 状态
线程从RUNNABLE状态到Timed Waiting状态的转换通常发生在调用了带有时间限制的等待方法,如Thread类的sleep(long millis)方法或Object类的wait(long timeout)方法。
当一个线程调用sleep(long millis)方法后,线程会进入Timed Waiting状态。在指定的时间段内,线程不会争夺CPU资源,而是处于休眠状态。一旦指定的时间过去,线程会重新进入就绪状态,等待系统分配CPU资源并继续执行。
另外,当一个线程调用了Object类的wait(long timeout)方法后,线程会释放占有的锁并进入Timed Waiting状态,等待其他线程通过notify()或notifyAll()方法来唤醒它,或者等待指定的时间段过去。如果指定的时间段内没有其他线程唤醒它,那么线程会自动重新进入就绪状态。
需要注意的是,线程从Timed Waiting状态到RUNNABLE状态的转换是由时间限制或其他线程的唤醒操作触发的。在Timed Waiting状态下,线程会等待一段时间或者被其他线程显式地唤醒后,才有机会重新进入就绪状态。
这种状态转换通常用于线程间的时间控制和同步操作,通过合理地使用sleep()、wait()等方法可以实现线程的定时等待和协调。
RUNNABLE到TERMINATED 状态
线程从RUNNABLE状态到TERMINATED状态的转换通常发生在线程执行完任务或由于异常退出时。
当一个线程处于RUNNABLE状态并且执行完了其run()方法中的代码,即任务完成时,线程会自动进入TERMINATED状态。在TERMINATED状态下,线程已经结束执行,不再具有任何运行状态。
另外,如果线程在执行过程中发生了未捕获的异常导致线程提前退出,也会使线程从RUNNABLE状态转换为TERMINATED状态。
需要注意的是,TERMINATED状态是最终状态,一旦线程进入该状态,就无法再回到其他状态。如果需要重新执行线程任务,必须创建一个新的线程对象并启动。
控制线程状态的转换是由JVM和操作系统来管理的,开发者可以通过合理的编码和使用线程控制方法来影响线程状态的转换,确保线程能够按照预期执行和完成任务。
更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)