Java线程的5种状态及状态之间转换

2023-10-30

Java中的线程的生命周期大体可分为5种状态。

 

1. 新建(NEW):新创建了一个线程对象。

2. 可运行(RUNNABLE):线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权 。

3. 运行(RUNNING):可运行状态(runnable)的线程获得了cpu 时间片(timeslice) ,执行程序代码。
4. 阻塞(BLOCKED):阻塞状态是指线程因为某种原因放弃了cpu 使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有机会再次获得cpu timeslice 转到运行(running)状态。阻塞的情况分三种: 

(一). 等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
(二). 同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
(三). 其他阻塞:运行(running)的线程执行Thread.sleep(long ms)或t.join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入可运行(runnable)状态。

5. 死亡(DEAD):线程run()、main() 方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

 

 

一.线程的状态图

     线程状态转换

 

二.初始状态

  1. 实现Runnable接口和继承Thread可以得到一个线程类,new一个实例出来,线程就进入了初始状态

三.可运行状态

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

四.运行状态

  1. 线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一一种方式。

五.死亡状态

  1. 当线程的run()方法完成时,或者主线程的main()方法完成时,我们就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。
  2. 在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

六.阻塞状态

  1. 当前线程T调用Thread.sleep()方法,当前线程进入阻塞状态。
  2. 运行在当前线程里的其它线程t2调用join()方法,当前线程进入阻塞状态。
  3. 等待用户输入的时候,当前线程进入阻塞状态。

七.等待队列(本是Object里的方法,但影响了线程)

  1. 调用obj的wait(), notify()方法前,必须获得obj锁,也就是必须写在synchronized(obj) 代码段内。
  2. 与等待队列相关的步骤和图
  • 线程1获取对象A的锁,正在使用对象A。
  • 线程1调用对象A的wait()方法。
  • 线程1释放对象A的锁,并马上进入等待队列。
  • 锁池里面的对象争抢对象A的锁。
  • 线程5获得对象A的锁,进入synchronized块,使用对象A。
  • 线程5调用对象A的notifyAll()方法,唤醒所有线程,所有线程进入锁池。||||| 线程5调用对象A的notify()方法,唤醒一个线程,不知道会唤醒谁,被唤醒的那个线程进入锁池。
  • notifyAll()方法所在synchronized结束,线程5释放对象A的锁。
  • 锁池里面的线程争抢对象锁,但线程1什么时候能抢到就不知道了。||||| 原本锁池+第6步被唤醒的线程一起争抢对象锁。多线程等待队列

 

八.锁池状态

  1. 当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入锁池状态。简言之,锁池里面放的都是想争夺对象锁的线程。
  2. 当一个线程1被另外一个线程2唤醒时,1线程进入锁池状态,去争夺对象锁。
  3. 锁池是在同步的环境下才有的概念,一个对象对应一个锁池。

九.几个方法的比较

  1. Thread.sleep(long millis),一定是当前线程调用此方法,当前线程进入阻塞,但不释放对象锁,millis后线程自动苏醒进入可运行状态。作用:给其它线程执行机会的最佳方式。
  2. Thread.yield(),一定是当前线程调用此方法,当前线程放弃获取的cpu时间片,由运行状态变会可运行状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。
  3. t.join()/t.join(long millis),当前线程里调用其它线程1的join方法,当前线程阻塞,但不释放对象锁,直到线程1执行完毕或者millis时间到,当前线程进入可运行状态。
  4. obj.wait(),当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout)timeout时间到自动唤醒。
  5. obj.notify()唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。

十.两个疑问

  1. 当对象锁被某一线程释放的一瞬间,锁池里面的哪个线程能获得这个锁?随机?队列FIFO?or sth else?
  2. 等待队列里许许多多的线程都wait()在一个对象上,此时某一线程调用了对象的notify()方法,那唤醒的到底是哪个线程?随机?队列FIFO?or sth else?java文档就简单的写了句:选择是任意性的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java线程的5种状态及状态之间转换 的相关文章

  • 禁止本地中断

    禁止本地CPU中断是确保一组内核语句被当作一个临界区处理的主要机制 这个机制的意义是 即使当硬件设备产生了一个IRQ信号时 中断禁止也让内核控制路径继续执行 因此 这就提供了一种有效的方式 确保内核控制路径中的一些中断处理程序能访问的数据结
  • 【C++11多线程】线程的创建与结束:thread

    文章目录 1 普通函数作为线程函数 1 1 thread 1 2 join 1 3 detach 1 4 joinable 2 函数对象作为线程函数 3 lambda表达式作为线程函数 4 类成员函数作为线程函数 5 向线程函数传递参数 1
  • gdb多线程调试

    先介绍一下GDB多线程调试的基本命令 info threads 显示当前可调试的所有线程 每个线程会有一个GDB为其分配的ID 后面操作线程的时候会用到这个ID 前面有 的是当前调试的线程 thread ID 切换当前调试的线程为指定ID的
  • 用Java Socket开发小型服务器,支持上千个并发

    Java Socket 套接字 socket 为两台计算机之间的通信提供了一种机制 在James Gosling注意到Java 语言之前 套接字就早已赫赫有名 该语言只是让您不必了解底层操作系统的细节就能有效地使用套接字 1 客户机 服务器
  • 自动化测试实现多线程

    自动化测试实现多线程 进程 进程就是一个程序在一个数据集上的一次动态执行过程 我们编写的程序用来描述进程要完成哪些功能以及如何完成 线程 线程页脚轻量级进程 他是一个基本的CPU执行单元 是进程中的实现 线程的出现是为了降低上下文切换的小号
  • QT多线程

    Qt多线程 1 QThread类 QThread类并不是代表一个新的线程 而是QT提供的一个接口 用于控制一个子线程 每个QThread的实例就代表着对一个新线程的一个控制类 对于第一次使用QT多线程的人 或许就会很迷惑很不适应 QThre
  • Java Thread Join

    join方法的作用 在A线程中调用了B线程的join 方法时 表示只有当B线程执行完毕时 A线程才能继续执行
  • 主线程中捕获子线程异常

    需求 主线程独立执行 无需等待子线程执行完毕 子线程如有异常抛出可自行catch 网上介绍的方法一般是 1 在线程内部进行try catch捕获异常 2 通过线程池的submit方法 获取Future对象 然后try catch Futur
  • AFX_MANAGE_STATE(AfxGetStaticModuleState())讲解

    以前写MFC的DLL的时候 总会在自动生成的代码框架里看到提示 需要在每一个输出的函数开始添加上AFX MANAGE STATE AfxGetStaticModuleState 一直不明白这样做的含义 也一直没有这样做 而且代码也工作得好好
  • java之Thread类详细分析(全)

    目录 前言 1 属性值 1 1 线程属性方法 2 常用方法 3 使用方法 前言 Thread是程序中的执行线程 jvm并发地运行多个执行线程 1 属性值 通过查看Thread源码 是继承Runnable接口的实现类 无论使用Runnable
  • 多线程问题分析thread

    多线程 进程概述 A 进程 进程指正在运行的程序 确切的来说 当一个程序进入内存运行 即变成一个进程 进程是处于运行过程中的程序 并且具有一定独立功能 简而言之 当前正在运动的程序 一个应用程序在内存中的执行区域 B 线程 线程是进程中的一
  • 关于CoInitialize()

    在msdn中对于CoInitialize的解释如下 Initializes the COM library on the current apartment and identifies the concurrency model as s
  • JAVA多线程--信号量(Semaphore)

    简介 信号量 Semaphore 有时被称为信号灯 是在多线程环境下使用的一种设施 它负责协调各个线程 以保证它们能够正确 合理的使用公共资源 一个计数信号量 从概念上讲 信号量维护了一个许可集 如有必要 在许可可用前会阻塞每一个 acqu
  • 第十三章:QT多线程(QThread)

    回顾 第一章 Qt的概述 第二章 在Ubuntu编写第一个Qt程序 第三章 Qt的字符串和字符编码 第四章 Qt的信号和槽 第五章 Qt容器窗口 父窗口 第六章 面向对象的Qt编程 第七章 Qt设计师使用 designer 第八章 Qt创造
  • 同步方法及同步代码块

    synchronized方法和synchronized块 synchronized方法必须获得对象的锁才能执行 否则线程阻塞 方法一旦执行 就独占此锁 直到方法返回才释放锁 后面被阻塞的线程才能获得这个锁 继续执行 synchronized
  • python多线程编程: 使用互斥锁同步线程

    由于每个线程互相独立 相互之间没有任何关系 你干你的 我干我的 互相不干扰 如果要几个线程同时干一件事怎么办 由于互相不走动 如果一个线程已经做过了 另一个线程再去做 不就重复了吗 很容易乱套 现在假设这样一个例子 有一个全局的计数num
  • c++11std::thread扩展

    最近 整理一下学习c 的文章 看到一篇文章 其中提到了thread local和std future 觉得这两东西很有趣 于是网上搜了一些资料 觉得很有帮助 希望可以对大家学习c 线程有所帮助 http www cnblogs com ha
  • python中的GIL详解

    python中的GIL详解 参考Python GIL 锁简述 GIL是什么 首先需要明确的一点是GIL并不是Python的特性 它是在实现Python解析器 CPython 时所引入的一个概念 就好比C 是一套语言 语法 标准 但是可以用不
  • thread_Timer(线程中定时器)

    package com gzhs zsd thread import java util Date import java util Timer import java util TimerTask Timer定时器运用 author 谢泽
  • Java并发编程:CountDownLatch、CyclicBarrier和 Semaphore

    Java并发编程 CountDownLatch CyclicBarrier和 Semaphore 2016 10 07 分类 基础技术 7 条评论 标签 并发 分享到 0 原文出处 海子 在java 1 5中 提供了一些非常有用的辅助类来帮

随机推荐

  • Keil5关于.h文件编译时遇见报错打不开时的解决方案

    添加路径即可
  • Centos设置ssh免密登录

    查看安装的ssh软件 rpm qa查询系统安装的所有软件 对前面rpm查询结果进行搜索ssh rpm qa grep ssh 安装netstat工具查询软件进程的端口号 yum y install net tool 使用netstat查询2
  • 品味树莓派:GPIO口定义、电气特性、启动状态等基础说明

    文章目录 目录 GPIO口定义 电气特性 启动状态 总结 目录 树莓派相比成品化的电脑来说有很多独立的GPIO口可供开发使用 可以方便的实现很多实物相关的功能 本文将对树莓派开放给用户的GPIO口的针脚定义 电气特性 启动状态等基础内容做个
  • svm多分类_数据挖掘算法——常用部分分类算法

    分类算法 分类是在一群已经知道类别标号的样本中 训练一种分类器 让其能够对某种未知的样本进行分类 分类算法属于一种有监督的学习 分类算法的分类过程就是建立一种分类模型来描述预定的数据集或概念集 通过分析由属性描述的数据库元组来构造模型 分类
  • OpenSSL之EVP(一)——数据结构及源码结构介绍

    EVP简介 Openssl EVP提供了丰富的密码学中的各种函数 Openssl 中实现了各种对称算法 摘要算法以及签名 验签算法 EVP 函数将这些具体的算法进行了封装 EVP 主要封装了如下功能函数 1 实现了 base64 编解码 B
  • 新浪期货数据接口

    附注 对于期货数据 一直在寻找互联网上能够获得的比较好的数据源 最近发现了 新浪期货 的数据源 可以提供一分钟的期货K线数据 http hq sinajs cn list TICKER 对于国内期货连续 Ticker为正常Ticker加个0
  • Deep Residual Network

    先阅读者两篇写的比较好的博客 https blog csdn net dulingtingzi article details 79870486 https blog csdn net qq 31050167 article details
  • 高德地图绘制标记点,点击弹出弹框进入第三方地图软件

    需求 根据经纬度绘制标记点 点击标记点弹出弹框和底部按钮 点击顶部弹框进入二级界面 点击底部按钮弹出第三方地图软件选择页 实现跨进程跳转 效果图 项目是公司项目 只放出重要部分代码 final Marker marker1 aMap add
  • 计算机图形学入门(八)-着色(插值、高级纹理映射)

    目录 重心坐标 应用纹理 1 纹理分辨率很小 2 纹理分辨率过大 纹理的应用 颜色 环境贴图 Environment Map 法线贴图 凹凸贴图 位移贴图 三维纹理和三维噪声 着色信息的记录 学习视频来源 GAMES101 现代计算机图形学
  • 【操作系统】进程间通信的五种方式

    引言 1 进程对白 管道 记名管道 套接字 1 管道 2 虫洞 套接字 3 信号 4 信号旗语 信号量 5 进程拥抱 共享内存 引言 进程作为人类的发明 自然免不了脱离人类的习性 也有通信需求 如果进程之间不进行任何通信 那么进程所能完成的
  • 关于你STM32F407片内FLASH擦除失败的问题

    近日 发现STM32F407片内FLASH在写入数据时某些情况下会出现扇区擦除不成功的情况 使用正点原子的代码测试也出一样的情况 网上搜索也没找到较为理想的答案 只有一篇文章遇到同样问题 也是使用了一个不太可靠的办法 但是好在可以解决问题
  • DM8无图形界面安装与使用

    本机实验环境 centos7 9 参考文档 数据库安装 达梦云适配中心文档 dameng com https eco dameng com docs zh cn start install dm linux prepare html 1 系
  • “红山开源”创新论坛

    ChinaOSC 2022 红山开源 创新论坛将于2022年8月20日14 00 17 00在陕西省西安高新国际会议中心召开 红山开源 创新论坛重点聚焦战略科技领域相关需求 邀请知名院士和专家共同探讨战略科研任务开源众创组织模式和项目孵化方
  • 部署tomcat时出现No artifacts marked for deployment

    这种错误主要是因为没有设置导出包 解决方法 File gt Project Structure gt Artifacts 然后点击ok 然后记得apply ok 此时再回到问题所在 点击Fix即可 或者如下
  • JAVA中的正则表达式

    一 正则表达式的构成 1 字符类 abc a b c abc 任何字符 除了a b c a zA Z a到z或A到Z 两头的字母包含在内 范围 2 预定义字符类 任何字符 d 数字 0 9 D 非数字 0 9 s 空白字符 t n x0B
  • Python爬虫JS解密详解,学会直接破解80%的网站(二)!!!

    文章目录 前言 1 网页查看 2 JS解密过程 细心看哦 3 解密答案 完整代码 CSDN独家福利降临 Python爬虫JS解密详解 学会直接破解80 的网站 25个爬虫项目宝藏教程 你值得拥有 前言 Glidedsky这关的JS解密不同于
  • js rsa加密_Python实现RSA(jsencrypt)加密的两种方式

    RSA是一种常用加密算法 经常用在前端向后端传送密码的时候 一 通过运行rsa js文件加密 rsa js文件下载地址 https gitee com youchuanming rsa jsencrypt import urllib pur
  • 常见排序算法的js实现

    常见排序算法的js实现 冒泡排序 选择排序
  • git 笔记/常见命令/as的fetch,pull ,update project的区别/标签管理

    Git概念汇总 头 HEAD 头 HEAD HEAD类似一个 指针 指向当前活动 分支 的 最新版本 工作区 Workspace 就是在电脑里能看到的项目代码库目录 是我们搬砖的地方 在这里我们可以新增文件 修改文件内容 或删除文件 此时的
  • Java线程的5种状态及状态之间转换

    Java中的线程的生命周期大体可分为5种状态 1 新建 NEW 新创建了一个线程对象 2 可运行 RUNNABLE 线程对象创建后 其他线程 比如main线程 调用了该对象的start 方法 该状态的线程位于可运行线程池中 等待被线程调度选