JAVA和Nginx 教程大全

网站首页 > 精选教程 正文

Java面试必考问题:线程的生命周期

wys521 2024-11-18 18:02:07 精选教程 22 ℃ 0 评论

线程和进程是操作系统中最重要的基本概念之一,JVM线程也是Java面试时经常问到的问题。Java线程虽然是JVM管理,但其最终还是映射到了操作系统内核线程上,由操作系统(OS)来完成线程的切换、调度,以及将线程任务分配到CPU上执行。

本文重点讨论Java线程的生命周期,和操作系统的线程概念也是基本一致的。

Java线程有哪些状态?

线程共有5种状态:初始(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)、死亡(Dead)。

初始状态(New):使用 new Thread() 方法新建一个线程。线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,不管哪种实现,只要new了就进入初始状态。

就绪状态(Runnable):又称为可执行状态。当线程对象调用了start()方法,就进入就绪状态,此时线程准备抢占CPU资源。

执行状态(Running):线程抢到CPU执行权之后,或者说是被OS选中了,线程就进入了运行状态。

阻塞状态(Blocked):阻塞状态是指线程由于某种原因放弃CPU使用权,临时停止执行。线程从阻塞状态进入就绪状态以后,才有机会转到执行状态。

死亡状态(Dead):线程任务执行完成或者异常退出了run()方法时,线程结束生命周期。

当线程正在进行某种不确定时长的任务时,Java就会收回CPU的执行权,从而合理应用CPU的资源。有三种情况会让执行线程进入阻塞状态。

(1)等待阻塞:执行的线程执行wait()方法,JVM会把该线程放入等待集(Wait Set)中。

(2)同步阻塞:执行的线程在获取某个对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入入口集(Entry Set)中。

(3)其他情况:执行的线程执行 sleep() join() 方法,或者发出了某个I/O请求,JVM会把该线程置为堵塞状态。

那么进入阻塞状态的线程如何重新转到执行状态呢?从上图中可以看出,线程在阻塞过程结束之后,会进入就绪状态,准备重新争夺CPU资源。不同情况下,阻塞线程进入就绪状态的条件也有所区别。

(1)等待阻塞的线程:进入这个状态后,线程是不能自己主动唤醒的,必须依靠其它线程调用notify()或notifyAll()方法才能被唤醒,线程被唤醒后会进入Entry Set,等待获取锁。

(2)同步阻塞的线程:线程进入Entry Set后,Entry Set里可能已经有了其它线程在等待获取锁,这时Entry Set中的线程处于先到先得的队列状态;线程获得锁后,就转入就绪状态。

(3)其他阻塞的线程:当sleep()join()结束后,或者IO执行完成,线程会重新进入就绪状态,等待系统分配时间片。

执行状态转移为就绪状态

如果执行中的线程调用了 yield() 方法,意味着它放弃了当前获得的CPU时间片,回到就绪状态,与其它线程处于同等竞争的地位,等待OS下次调度这个线程进入执行状态。

我会持续更新关于物联网、云原生以及数字科技方面的文章,用简单的语言描述复杂的技术,也会偶尔发表一下对IT产业的看法,欢迎大家关注,谢谢。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表