线程有哪些状态

线程的生命周期

线程在Java中有以下几种状态:

  1. 新建(New):初始化状态
  2. 就绪(Runnable):可运行、运行状态
  3. 阻塞(Blocked):等待状态,无时限
  4. 等待(Waiting):等待状态,有时限
  5. 超时等待(Timed Waiting):就绪状态
  6. 终止(Terminated):终止状态
     

线程状态枚举代码

public static enum State {NEW,RUNNABLE,BLOCKED,WAITING,TIMED_WAITING,TERMINATED;private State() {}}

线程的状态流转图

线程各个状态说明

新建(New):当线程对象被创建但还没有调用start()方法时,线程处于新建状态。

就绪(Runnable):一旦线程调用了start()方法,它进入就绪状态。线程处于就绪状态时,表示它已经准备好被JVM调度执行,只是还没有得到CPU的时间片。

  1. 就绪状态只是说你自个儿运行,调度程序没有挑选到你,你就永远是就绪状态。
  2. 调用线程的start()方法,此线程进入就绪状态。
  3. 当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入就绪状态。
  4. 当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入就绪状态。
  5. 锁池里的线程拿到对象锁后,进入就绪状态。

运行(Running):当线程获得CPU时间片并开始执行时,它进入运行状态。

阻塞(Blocked):线程因为某些原因放弃CPU使用权,暂时停止运行,进入阻塞状态。比如线程在等待某个资源,或者调用了sleep()、wait()等方法。

  1. 阻塞状态是线程阻塞在进入synchronized关键字修饰的方法或代码块(获取锁)之前时的状态。

等待(Waiting):线程进入等待状态,表示它正在等待其他线程做出一些特定动作(通常是通知或中断)。

  1. 调用sleep或是wait方法后线程处于WAITING状态,等待被唤醒。

超时等待(Timed Waiting):线程在等待指定的时间后会自动转为就绪状态。

  1. 调用sleep或是wait方法后线程处于TIMED_WAITING状态,等待被唤醒或时间超时自动唤醒。

终止(Terminated):线程执行完任务后或者因异常退出了run()方法,进入终止状态。

  1. 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
  2. 在一个终止的线程上调用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)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/174335.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring核心

Spring Framework Spring的两个核心IOC控制反转IOC容器依赖注入DIIOC容器实现注解管理BeanBean对象定义Bean对象获取 AOP面向切面编程 添加依赖入门案例注解通过Spring创建Java bean对象 xml管理Bean案例main下创建bean.XMl文件 DI依赖注入案例创建Spring配置文件 bean-di.xml …

H5游戏源码分享-网页版2048小游戏

H5游戏源码分享-网页版2048小游戏 玩过的都懂 <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>分享2048到朋友圈&#xff0c;将免费参加南山郡8.17号啤酒狂欢节&#xff01;</title><link href"style/main…

Day29力扣打卡

打卡记录 美丽塔 II&#xff08;前后缀分解 单调栈&#xff09; 链接 大佬的题解 class Solution:def maximumSumOfHeights(self, a: List[int]) -> int:n len(a)suf [0] * (n 1)st [n] # 哨兵s 0for i in range(n - 1, -1, -1):x a[i]while len(st) > 1 and …

简单理解 Sentinel 滑动窗口实现原理

theme: serene-rose 1. 引言 Hi&#xff0c;你好&#xff0c;我是有清 对于刚经历过双 11 的电商人来说&#xff0c;限流这个词肯定在 10.24 的晚 20.00 点被提起过 限流作为保护我们系统不被流量冲垮的手段之一&#xff0c;建议每个电商人深入了解学习&#xff0c;什么&#x…

应急响应练习1

目录 1. 提交攻击者的IP地址 2. 识别攻击者使用的操作系统 3. 找出攻击者资产收集所使用的平台 4. 提交攻击者目录扫描所使用的工具名称 5. 提交攻击者首次攻击成功的时间&#xff0c;格式&#xff1a;DD /MM/YY:HH:MM:SS 6. 找到攻击者写入的恶意后门文件&#xff0c;提…

黑群晖断电导致存储空间已损毁修复记录

黑群晖断电2次,担心的事情还是发生了,登录后提示存储空间已损毁...... 开干!! 修复方式: 1.使用SSH登录到群晖,查看相关信息 # 登录后先获取最高权限 root@DiskStation:~# sudo -i # 检测存储池状态 root@DiskStation:~# cat /proc/mdstat Personalities : [linear] […

Java 算法篇-深入了解单链表的反转(实现:用 5 种方式来具体实现)

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 单链表的反转说明 2.0 单链表的创建 3.0 实现单链表反转的五种方法 3.1 实现单链表反转 - 循环复制&#xff08;迭代法&#xff09; 3.2 实现单链表反转 - 头插法 3…

卷积神经网络(1)

目录 卷积 1 自定义二维卷积算子 2 自定义带步长和零填充的二维卷积算子 3 实现图像边缘检测 4 自定义卷积层算子和汇聚层算子 4.1 卷积算子 4.2 汇聚层算子 5 学习torch.nn.Conv2d()、torch.nn.MaxPool2d()&#xff1b;torch.nn.avg_pool2d()&#xff0c;简要介绍使用方…

数据结构-堆和二叉树

目录 1.树的概念及结构 1.1 树的相关概念 1.2 树的概念 1.3 树的表示 1.4 树在实际中的应用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树的概念及结构 2.1 概念 2.2 特殊的二叉树 2.3 二叉树的存储 3.堆的概念及结构 4.堆的实现 初始化堆 堆的插入…

计算机组成原理:大而快——层次化存储

原文链接www.xiaocr.fun/index.php/2023/11/14/计算机组成原理大而快-层次化存储/ 引言 关于两种局部性 时间局部性&#xff1a;如果某个数据被访问&#xff0c;那么在不久的将来它可能再次被访问空间局部性&#xff1a;如果某个数据项被访问&#xff0c;与它相邻的数据项可…

Qt文档阅读笔记-Fetch More Example解析

Fetch More Example这个例子说明了如何在视图模型上添加记录。 这个例子由一个对话框组成&#xff0c;在Directory的输入框中&#xff0c;可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。 当有大量数据时&#xff0c;需要对视图模型进行批量增…

剑指 Offer 07. 重建二叉树

title: 剑指 Offer 07. 重建二叉树 tags: 二叉树递归 categories:算法剑指 Offer 题目描述 输入某二叉树的前序遍历和中序遍历的结果&#xff0c;请构建该二叉树并返回其根节点。 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 示例 1: Input: preorder [3,9,…