【五分钟面试题】线程的生命周期和状态切换

前言

面试题:”你知道线程的生命周期吗?请说说对线程状态的理解“。

知识点

线程的生命周期是指一个完整的线程,要经过新建(New)可运行状态(Runable)阻塞状态(Blocked)等待状态(Waiting)、和终止状态(Terminated)五种生命状态,并且它们之间是可以相互切换的:

【五分钟面试题】线程的生命周期和状态切换_第1张图片

 

1.new

new状态就是当你创建线程对象这个阶段的线程状态,此时新建了一个线程对象,但是还没有调用start()方法,所以这个阶段下线程还是不存在的。只有调用Thread.start()方法后,JVM才会真正创建一个线程。

在调用完start()方法后,线程便进入到Runnable状态:

【五分钟面试题】线程的生命周期和状态切换_第2张图片

 

2.Runnable

可运行状态指的就是当前线程拥有CPU的调度资格,随时可以切换到运行状态,当CPU时间片没有分配给当前线程的时候,它就永远处于可运行状态。所以会有以下几种情况线程会处于Runnable状态:

  • 线程执行完start()方法,此时由new状态切换为Runnable
  • 当前线程sleep()结束,其它线程join()结束,当某个线程拿到了锁后,那么这些线程会因为拿不到锁而进入可运行状态,从而节约CPU资源
  • 当前线程CPU时间片执行完了,并且执行yield()方法,当前线程也会进入到可运行状态

【五分钟面试题】线程的生命周期和状态切换_第3张图片

 

3.Running

一个线程在拥有CPU时间片后从可运行状态切换为运行状态。处于运行状态的线程意味着掌握CPU的调度资格,可以进行程序的执行。

在这个阶段不会有太复杂的动作,主要就是执行程序。我们要注意的是,这个状态会由于一些因素而让线程向前或者向后发生状态的改变:

  • 当CPU时间片走完后,该线程就会进行Runnable状态
  • 若线程主动调用yield(),就意味放弃了CPU的执行权,那么当前线程就会进入Runnable状态。但是yield()方法不会每次都生效,只有当CPU资源紧张的时候程序才会判定你放弃了线程而将时间片让给别人
  • 若调用sleep()或者wait()方法,线程就会进入阻塞状态
  • 当前线程若和其他线程竞争,获取不到锁资源就会进入阻塞状态
  • 若当前线程所执行到的代码逻辑有调用stop()方法,则会进入Terminated状态

【五分钟面试题】线程的生命周期和状态切换_第4张图片

4.Blocked

处于Blocked状态的线程是不会持有CPU时间片的,通常线程是由Running状态切换到Block状态的,我们刚刚已经解释过了。现在来讲讲处于该状态的线程如何切换出去:

  • 线程阻塞的时间走完,比如已经出了阻塞队列、获取到锁资源或者休眠结束这样的场景,那么就会进入Runnable状态
  • 线程阻塞状态被打断,调用了interrupt()方法,那么就会进入Runnable状态
  • 若当前线程所执行到的代码逻辑有调用stop()方法,则会进入Terminated状态

【五分钟面试题】线程的生命周期和状态切换_第5张图片

5.Terminated状态

当一个线程进入到Terminated状态后,就代表它的生命周期已经结束,所以不会再切换到其它任何状态,所以它是线程的最终状态。通常有三种情况会进入到Terminated:

  • 当前线程持有时间片并且执行完任务,则线程正常结束
  • 任何导致线程意味结束的情况,如一个未捕获的异常终止了run()方法而使线程从Running直接进入Terminated

可以使用isAlive()方法判断线程是否是可以运行的。若返回true则代表当前线程处于Running或者Blocked状态,意味着可以随时切换到运行状态。若返回false则代表线程还未调用start()方法进入可运行状态或者线程已经进入了Terminated。

总结

这个面试题考察你对Java线程基础的理解,重点:线程所处的五个状态、每个状态的特点、什么情况下会切换到别的状态。

回答了以上三个重点,无论哪个公司,面试官都会感到满意。

我是fancy,这里是《五分钟面试题》系列,如果觉得本文对你有所收获,可以三连支持一下呀 我们下次见~

你可能感兴趣的:(五分钟面试题,java,开发语言,java-ee,面试)