您现在的位置是:首页 > 正文

面试必答题“聊聊Java中线程的生命周期状态”如何破?

2024-01-30 23:50:40阅读 0

“聊聊Java中线程的生命周期状态吧!”

这几乎是一道面试必答题,这道题怎么答才是最佳答案呢?本文就带大家来破解一下!

01
一张图说明线程生命周期

JVM源码中将线程的生命周期分为新建(New)、可运行(Runnable)、阻塞(Blocked)、等待(Waiting)、超时等待(Timed_Waiting)和终止(Terminated)这6种状态。

在系统运行过程中不断有新的线程被创建,老的线程在执行完毕后被清理,线程在排队获取共享资源或者锁时将被阻塞,因此运行中的线程会在可运行、阻塞、等待状态之间来回切换。

线程的具体状态转化流程如图所示。

在这里插入图片描述

02
线程生命周期状态转化流程

(1)调用new方法新建一个线程,这时线程处于新建状态。

(2)调用start方法启动一个线程,这时线程处于可运行状态。可运行状态中又分:就绪(Ready)和运行中(Running)两种状态。处于就绪状态的线程等待线程获取CPU资源,在等待其获取CPU资源后线程会执行run方法进入运行中状态;正在运行的线程在调用了yield方法或失去处理器资源时,会再次进入就绪状态。

(3)正在运行中的线程在执行了sleep方法、I/O阻塞、等待同步锁、等待通知、调用suspend方法等操作后,会挂起并进入阻塞状态。阻塞状态的线程由于出现sleep时间已到、I/O方法返回、获得同步锁、收到通知、调用resume方法等情况,会再次进入可运行状态中的就绪状态,等待CPU时间片的轮询。该线程在获取CPU资源后,会再次进入运行状态。

(4)当线程调用了Object.wait ()、Object.join()、LockSupport.park()后线程进入等待状态。等待状态的线程调用Object.notify ()、Object. notifyAll()、LockSupport.unpark(Thread)方法后会再次进入可运行状态。

(5)当可运行状态的线程调用Thread.sleep(long)、Object.wait(long)、Thread.join(long)、LockSupport.parkNanos()、LockSupport.parkUntil()时线程会进入超时等待状态。当超时等待的线程出现超时时间到、等待进入synchronized方法、等待进入synchronized块或者调用Object.notify ()、Object. notifyAll()、LockSupport.unpark(Thread)时会再次进入可运行状态。

(6)处于可运行状态的线程,在调用run方法或call方法正常执行完成、调用stop方法停止线程或者程序执行错误导致异常退出时,会进入终止状态。

03
线程生命周期详解

新建状态(New)

在Java中使用new关键字创建一个线程,新创建的线程将处于新建状态。在创建线程时主要是为线程分配内存并初始化其成员变量的值。

就绪状态:Runnable

新建的线程对象在调用start方法之后将转为可运行状态。运行状态中又分:就绪(Ready)和运行中(Running)两种状态。就绪状态指的是JVM完成了方法调用栈和程序计数器的创建,等待该线程的调度和运行。

就绪状态的线程在竞争到CPU的使用权并开始执行run方法的线程执行体时,会转为运行中状态,处于运行中状态的线程的主要任务就是执行run方法中的逻辑代码。

阻塞状态:Blocked

运行中的线程会主动或被动地放弃 CPU 的使用权并暂停运行,此时该线程将转为阻塞状态,直到再次进入可运行状态,才有机会再次竞争到CPU使用权并转为运行状态。阻塞状态分为如下三种。

(1)等待阻塞:在运行状态的线程调用o.wait方法时,JVM会把该线程放入等待队列(Waitting Queue)中,线程转为阻塞状态。

(2)同步阻塞:在运行状态的线程尝试获取正在被其他线程占用的对象同步锁时,JVM会把该线程放入锁池(Lock Pool)中,此时线程转为阻塞状态。

(3)其他阻塞:运行状态的线程在执行Thread.sleep(long ms)、Thread.join()或者发出I/O请求时,JVM会把该线程转为阻塞状态。直到sleep()状态超时、Thread.join()等待线程终止或超时,或者I/O处理完毕,线程才重新转为可运行状态。

等待状态:Waiting

当线程调用了Object.wait()、Thread.join()、LockSupport.park()会进入等待状态。处于等待状态的线程正在等待另一个线程执行指定的操作。例如,调用Object.wait()的一个线程对象正在等待另一个线程调用该对象的Object.notify()或Object.notifyAll()。调用thread .join()的线程正在等待指定的线程退出。

超时等待状态:Timed_Waiting

超时等待和等待状态的不同是,超时等待状态的线程经过超时时间后会自动唤醒。当线程调用了Thread.sleep ()、Object.wait(long)、Thread.join(long)、LockSupport.parkNanos()、LockSupport.parkUntil()后线程会进入超时等待状态。

线程终止:Terminated

线程在以如下三种方式结束后转为终止状态。

◎ 线程正常结束:run方法或call方法执行完成。

◎ 线程异常退出:运行中的线程抛出一个Error或未捕获的Exception,线程异常退出。

◎ 手动结束:调用线程对象的stop方法手动结束运行中的线程(该方式会瞬间释放线程占用的同步对象锁,导致锁混乱和死锁,不推荐使用)。

本文节选自《Offer来了:Java面试核心知识点精讲(第2版)》!

在这里插入图片描述

王磊 著

超强Java面试宝典

超详尽Java知识点速查手册

Java面试官的超趁手Java题库参考书

一书在手,Java我有

本书讲解Java面试中常被问及的核心知识点,涉及Java基础、Java并发编程、JVM、Java高并发网络编程、Spring基础、Netflix的原理及应用、Spring Cloud Alibab的原理及应用、数据结构、Java中常用算法的原理及其Java实现、关系数据库及分布式事务、分布式缓存的原理及应用、ZooKeeper的原理及应用、Kafka的原理及应用、Elasticsearch的原理及应用、设计模式的概念及其Java实现。

本书内容全面、细致,既可帮助读者迅速查找Java知识点,也可帮助读者完善其Java知识体系;不但可以作为Java面试知识速通手册,也可以作为Java程序员的案头手册。

网站文章

  • C语言,环形队列

    C语言,环形队列

    什么是环形队列?环形缓冲区是一个非常典型的数据结构,这种数据结构符合生产者,消费者模型,可以理解它是一个水坑,生产者不断的往里面灌水,消费者就不断的从里面取出水。那就可能...

    2024-01-30 23:50:11
  • 软件测试 理念 价值,软件测试价值观-SMBT新理念

    2、Most bug:最多Bug量变到质变是事物的变化规律,测试也如此,只有Bug的量上去了,产品的质量才能有所改观,如果Bug在数量上上不去,这对测试活动有信心谈何容易,一旦遇到这种情况测试经理们就...

    2024-01-30 23:50:01
  • ESP32开发:Clion配置IDF

    ESP32开发:Clion配置IDF

    可以通过安装包进行安装,如下图:下载链接如下:https://dl.espressif.cn/dl/esp-idf/?idf=4.4安装好后,IDF会添加环境变量IDF_TOOLS_PATH,如果要安...

    2024-01-30 23:49:53
  • idea连接数据库出错

    idea连接数据库出错

    解决Server returns invalid timezone. Go to ‘Advanced’ tab and set ‘serverTimezone’ property manually. serverTimezone 改为CST

    2024-01-30 23:49:24
  • STM32CubeMX+FreeRTOS实验---使用os timer

    STM32CubeMX+FreeRTOS实验---使用os timer

    在STM32CubeMX的FreeRTOS配置中,使能FreeRTOS的Software Timer功能 修改timer的名称及callback名称等 可以看到,在生成工程的main.c文件的main函数中,有以下code /* Create the timer(s) */ /* definition and creation of myTimer01 */ osTime

    2024-01-30 23:49:10
  • NC添加客户端远程监听 agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=30.12.130.134:8777

    NC添加客户端远程监听 agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=30.12.130.134:8777

    NC添加客户端远程监听 agentlib:jdwp=transport=dt_socket,suspend=n,server=y,address=30.12.130.134:8777

    2024-01-30 23:48:41
  • kubernetes学习笔记-dashboard

    kubernetes学习笔记-dashboard

    2024-01-30 23:48:32
  • Jmeter性能压测 —— 高并发思路

    Jmeter性能压测 —— 高并发思路

    条件:接口响应时间 性能指标 -- 推导 --只需要1台与服务器相同配置的机器能完成5000/s并发量即可(类似数学中的同理可得,以此类推)

    2024-01-30 23:48:25
  • BSDragView

    BSDragView一个实现了任意位置拖动的view支持左右粘边,上下粘边效果效果gitHub地址:github.com/FreeBaiShun…用法新创建一个自定义的view继承与BSDragView直接使用这个自定义view即可支持任意位置拖动功能//1. 自定义view@interface MyView : BSDragView@end//2. 使用这个v...

    2024-01-30 23:48:19
  • lodash入门

    简介Lodash是一个著名的javascript原生库,不需要引入其他第三方依赖。是一个意在提高开发者效率,提高JS原生方法性能的JS库。简单的说就是,很多方法lodash已经帮你写好了,直接调用就行,不用自己费尽心思去写了,而且可以统一方法的一致性。Lodash使用了一个简单的 _ 符号,就像Jquery的 $ 一样,十分简洁。类似的还有Underscore.js和Lazy.js支持ch...

    2024-01-30 23:47:50