前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试系列之-线程的生命周期(JAVA基础)

面试系列之-线程的生命周期(JAVA基础)

作者头像
用户4283147
发布2023-08-21 20:19:47
1940
发布2023-08-21 20:19:47
举报
文章被收录于专栏:对线JAVA面试

线程生命状态说明

Thread.State是一个内部枚举类,定义了6个枚举常量,分别代表Java线程的6种状态:

代码语言:javascript
复制
public static enum State {    NEW, //新建    RUNNABLE, //可执行:包含操作系统的就绪、运行两种状态    BLOCKED, //阻塞    WAITING, //等待    TIMED_WAITING, //限时等待    TERMINATED; //终止}

NEW状态:创建成功但是没有调用start()方法启动的Thread线程实例都处于NEW状态。

TIMED_WAITING状态:线程处于一种特殊的等待状态,准确地说,线程处于限时等待状态

(1)Thread.sleep(int n):使得当前线程进入限时等待状态,等待时间为n毫秒。

(2)Object.wait():带时限的抢占对象的monitor锁。

(3)Thread.join():带时限的线程合并。

(4)LockSupport.parkNanos():让线程等待,时间以纳秒为单位。

(5)LockSupport.parkUntil():让线程等待,时间可以灵活设置。

Thread.yield()方法作用是:暂停当前正在执行的线程对象(及放弃当前拥有的cup资源), 并执行其他线程。yield()做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其 他线程获得运行机会。因此使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

NEW:毫无疑问表示的是刚创建的线程,还没有开始启动。

RUNNABLE: 表示线程已经触发start()方式调用,线程正式启动,线程处于运行中状态。

BLOCKED:表示线程阻塞,等待获取锁,如碰到synchronized、lock等关键字等占用临界区的情况,一旦获取到锁就进行RUNNABLE状态继续运行。

WAITING:表示线程处于无限制等待状态,等待一个特殊的事件来重新唤醒,如通过wait()方法进行等待的线程等待一个notify()或者notifyAll()方法,通过join()方法进行等待的线程等待目标线程运行结束而唤醒,一旦通过相关事件唤醒线程,线程就进入了RUNNABLE状态继续运行。

TIMED_WAITING:表示线程进入了一个有时限的等待,如sleep(3000),等待3秒后线程重新进行RUNNABLE状态继续运行。

TERMINATED:表示线程执行完毕后,进行终止状态。

需要注意的是,一旦线程通过start方法启动后就再也不能回到初始NEW状态,线程终止后也不能再回到RUNNABLE状态。

线程状态切换详细说明

NEW状态

通过new Thread(…)已经创建线程,但尚未调用start()启动线程,该线程处于NEW(新建)状态。虽然前面介绍了4种方式创建线程,但是其中的其他三种方式本质上都是通过new Thread()创建线程,仅仅是创建了不同的target执行目标实例(如Runnable实例)。

RUNNABLE状态

Java把Ready(就绪)和Running(执行)两种状态合并为一种状态:RUNNABLE(可执行)状态(或者可运行状态)。调用了线程的start()实例方法后,线程就处于就绪状态。此线程获取到CPU时间片后,开始执行run()方法中的业务代码,线程处于执行状态。

就绪状态

就绪状态仅仅表示线程具备运行资格,如果没有被操作系统的调度程序挑选中,线程就永远处于就绪状态。当前线程进入就绪状态的条件大致包括以下几种:

·调用线程的start()方法,此线程就会进入就绪状态。

·当前线程的执行时间片用完。

·线程睡眠(Sleep)操作结束。

·对其他线程合入(Join)操作结束。

·等待用户输入结束。

·线程争抢到对象锁(Object Monitor)。

·当前线程调用了yield()方法出让CPU执行权限。

执行状态

线程调度程序从就绪状态的线程中选择一个线程,被选中的线程状态将变成执行状态。这也是线程进入执行状态的唯一方式。

BLOCKED状态

处于BLOCKED(阻塞)状态的线程并不会占用CPU资源,以下情况会让线程进入阻塞状态:

(1)线程等待获取锁

等待获取一个锁,而该锁被其他线程持有,则该线程进入阻塞状态。当其他线程释放了该锁,并且线程调度器允许该线程持有该锁时,该线程退出阻塞状态。

(2)IO阻塞

线程发起了一个阻塞式IO操作后,如果不具备IO操作的条件,线程就会进入阻塞状态。IO包括磁盘IO、网络IO等。IO阻塞的一个简单例子:线程等待用户输入内容后继续执行。

WAITING状态

处于WAITING(无限期等待)状态的线程不会被分配CPU时间片,需要被其他线程显式地唤醒,才会进入就绪状态。线程调用以下3种方法会让自己进入无限等待状态:

·Object.wait()方法,对应的唤醒方式为:

·Object.notify()/Object.notifyAll()。

·Thread.join()方法,对应的唤醒方式为:被合入的线程执行完毕。

·LockSupport.park()方法,对应的唤醒方式为:

·LockSupport.unpark(Thread)。

TIMED_WAITING状态

处于TIMED_WAITING(限时等待)状态的线程不会被分配CPU时间片,如果指定时间之内没有被唤醒,限时等待的线程会被系统自动唤醒,进入就绪状态。以下3种方法会让线程进入限时等待状态:

·Thread.sleep(time)方法,对应的唤醒方式为:sleep睡眠时间结束。

·Object.wait(time)方法,对应的唤醒方式为:调用

·Object.notify()/Object.notifyAll()主动唤醒,或者限时结束。

·LockSupport.parkNanos(time)/parkUntil(time)方法,对应的唤醒方式

为:线程调用配套的LockSupport.unpark(Thread)方法结束,或者线程停止(park)时限结束。

进入BLOCKED状态、WAITING状态、TIMED_WAITING状态的线程都会让出CPU的使用权;另外,等待或者阻塞状态的线程被唤醒后,进入Ready状态,需要重新获取时间片才能接着运行。

TERMINATED状态

线程结束任务之后,将会正常进入TERMINATED(死亡)状态;或者说在线程执行过程中发生了异常(而没有被处理),也会导致线程进入死亡状态。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 对线JAVA面试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线程生命状态说明
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档