s001网站建设设计/南宁网站建设优化服务
1. 前言
本节内容主要是对多线程的 6 种状态进行详细讲解,具体内容点如下:
- 抛开语言,谈操作系统的线程的生命周期及线程 5 种状态,这是我们学习 Java 多线程 6 种状态的基础;
- 掌握 Java 的线程生命周期及 6 种线程状态,是我们本节课程的重点内容;
- 理解 Java 线程 6 种状态的定义,并且通过代码实例进行实战演练,更深入的掌握线程的 6 种不同状态,是我们本节内容的核心知识;
- 掌握 Java 线程不同状态之间的转变关系,更好地理解线程的不同状态,是我们本节课程的重点。
2. 操作系统线程的生命周期
定义:当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态。在线程的生命周期中,它要经过新建 (New)、就绪(Runnable)、运行(Running)、阻塞 (Blocked),和死亡 (Dead) 5 种状态。
从线程的新建 (New) 到死亡 (Dead),就是线程的整个生命周期。
下面我们分别对 5 种不同的状态进行概念解析。
新建 (New):操作系统在进程中新建一条线程,此时线程是初始化状态。
就绪 (Runnable):就绪状态,可以理解为随时待命状态,一切已准备就绪,随时等待运行命令。
运行 (Running):CPU 进行核心调度,对已就绪状态的线程进行任务分配,接到调度命令,进入线程运行状态。
阻塞 (Blocked):线程锁导致的线程阻塞状态。共享内存区域的共享文件,当有两个或两个以上的线程进行非读操作时,只允许一个线程进行操作,其他线程在第一个线程未释放锁之前不可进入操作,此时进入的一个线程是运行状态,其他线程为阻塞状态。
死亡 (Dead):线程工作结束,被操作系统回收。
3. Java 的线程的生命周期及状态
定义: 在 Java 线程的生命周期中,它要经过新建(New),运行(Running),阻塞(Blocked),等待(Waiting),超时等待(Timed_Waiting)和终止状态(Terminal)6 种状态。
从线程的新建(New)到终止状态(Terminal),就是线程的整个生命周期。
Tips :与操作系统相比, Java 线程是否少了 “就绪” 状态 ?其实 Java 线程依然有就绪状态,只不过 Java 线程将 “就绪(Runnable)" 和 “运行(Running)” 两种状态统一归结为 “运行(Running)” 状态。
我们来看下 Java 线程的 6 种状态的概念。
新建 (New):实现 Runnable 接口或者继承 Thead 类可以得到一个线程类,new 一个实例出来,线程就进入了初始状态。
运行 (Running):线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一方式。
阻塞 (Blocked):阻塞状态是线程在进入 synchronized 关键字修饰的方法或者代码块时,由于其他线程正在执行,不能够进入方法或者代码块而被阻塞的一种状态。
等待 (Waiting):执行 wait () 方法后线程进入等待状态,如果没有显示的 notify () 方法或者 notifyAll () 方法唤醒,该线程会一直处于等待状态。
超时等待 (Timed_Waiting):执行 sleep(Long time)方法后,线程进入超时等待状态,时间一到,自动唤醒线程。
终止状态 (Terminal):当线程的 run () 方法完成时,或者主线程的 main () 方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
4. 新建(New)状态详解
实例:
public class ThreadTest implements Runnable{@Overridepublic void run() {System.out.println("线程:"+Thread.currentThread()+" 正在执行...");}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new ThreadTest()); //线程 创建(NEW)状态}
}
这里仅仅对线程进行了创建,没有执行其他方法。 此时线程的状态就是新建 (New) 状态。
Tips:新建(New)状态的线程,是没有执行 start () 方法的线程。
5. 运行(Running)状态详解
定义: 线程调度程序从可运行池中选择一个线程作为当前线程时线程所处的状态。这也是线程进入运行状态的唯一方式。
public class ThreadTest implements Runnable{.......public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new ThreadTest()); //线程 创建(NEW)状态t1. start(); //线程进入 运行(Running)状态}
}
当线程调用 start () 方法后,线程才进入了运行(Running)状态。
6. 阻塞(Blocked)状态详解
定义: 阻塞状态是线程阻塞在进入 synchronized 关键字修饰的方法或者代码块时的状态。
我们先来分析如下代码。
实例:
public class DemoTest implements Runnable{@Overridepublic void run() {testBolockStatus();}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new DemoTest()); //线程 t1创建(NEW)状态t1.setName("T-one");Thread t2 = new Thread(new DemoTest()); //线程 t2创建(NEW)状态t2.setName("T-two");t1. start(); //线程 t1 进入 运行(Running)状态t2. start(); //线程 t2 进入 运行(Running)状态}public static synchronized void testBolockStatus(){ // 该方法被 synchronized修饰System.out.println("我是被 synchronized 修饰的同步方法, 正在有线程" +Thread.currentThread().getName() +"执行我,其他线程进入阻塞状态排队。");}
}
代码分析:
首先,请看关键代码:
t1. start(); //线程 t1 进入 运行(Running)状态
t2. start(); //线程 t2 进入 运行(Running)状态
我们将线程 t1 和 t2 进行 运行状态的启动,此时 t1 和 t2 就会执行 run () 方法下的 sync testBolockStatus () 方法。
然后,请看关键代码:
public static synchronized void testBolockStatus(){ // 该方法被 synchronized修饰
testBolockStatus () 方法是被 synchronized 修饰的同步方法。当有 2 条或者 2 条以上的线程执行该方法时, 除了进入方法的一条线程外,其他线程均处于 “阻塞” 状态。
最后,我们看下执行结果:
我是被 synchronized 修饰的同步方法, 正在有线程T-one执行我,其他线程进入阻塞状态排队。
我是被 synchronized 修饰的同步方法, 正在有线程T-two执行我,其他线程进入阻塞状态排队。
执行结果解析:我们有两条线程, 线程名称分别为: T-one 和 T-two。
- 执行结果第一条: T-one 的状态当时为 运行(Running)状态,T-two 状态为 阻塞(Blocked)状态;
- 执行结果第二条: T-two 的状态当时为 运行(Running)状态,T-one 状态为 阻塞(Blocked)状态。
7. 等待(Waiting)状态详解
定义: 执行 wait () 方法后线程进入等待状态,如果没有显示的 notify () 方法或者 notifyAll () 方法唤醒,该线程会一直处于等待状态。
我们通过代码来看下,等待(Waiting)状态。
实例:
public class DemoTest implements Runnable{@Overridepublic void run() {try {testBolockStatus();} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(new DemoTest()); //线程 t1创建(NEW)状态t1.setName("T-one");t1. start(); //线程进入 运行 状态}public synchronized void testBolockStatus() throws InterruptedException {System.out.println("我是线程:" + Thread.currentThread().getName() + ". 我进来了。");this.wait(); //线程进入 等待状态 ,没有其他线程 唤醒, 会一直等待下去System.out.println("我是被 synchronized 修饰的同步方法, 正在有线程" +Thread.currentThread().getName() +"执行我,其他线程进入阻塞状态排队。");}
}
注意看下关键代码:
this.wait(); //线程进入 等待状态 ,没有其他线程 唤醒, 会一直等待下去
这里调用了 wait () 方法。线程进入 等待(Waiting)状态。如果没有其他线程唤醒,会一直维持等待状态。
运行结果:
我是线程:T-one. 我进来了。
没有办法打印 wait () 方法后边的执行语句,因为线程已经进入了等待状态。
8. 超时等待(Timed-Waiting)状态详解
定义: 执行 sleep(Long time)方法后,线程进入超时等待状态,时间一到,自动唤醒线程。
我们通过代码来看下,超时等待(Timed-Waiting)状态。
实例:
public class DemoTest implements Runnable{@Overridepublic void run() {.....}public static void main(String[] args) throws InterruptedException {.....}public synchronized void testBolockStatus() throws InterruptedException {System.out.println("我是线程:" + Thread.currentThread().getName() + ". 我进来了。");Thread.sleep(5000); //超时等待 状态 5 秒后自动唤醒线程。System.out.println("我是被 synchronized 修饰的同步方法, 正在有线程" +Thread.currentThread().getName() +"执行我,其他线程进入阻塞状态排队。");}
}
注意看下关键代码:
Thread.sleep(5000); //超时等待 状态 5 秒后自动唤醒线程。
这里调用了 sleep () 方法。线程进入超时等待(Timed-Waiting)状态。超时等待时间结束,自动唤醒线程继续执行。
运行结果:5 秒后,打印第二条语句。
我是线程:T-one. 我进来了。
我睡醒了。我是被 synchronized 修饰的同步方法, 正在有线程T-one执行我,其他线程进入阻塞状态排队。
9. 终止(Terminal)状态定义
定义: 当线程的 run () 方法完成时,或者主线程的 main () 方法完成时,我们就认为它终止了。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦终止了,就不能复生。
10. 小结
本节的重中之重在于线程的 6 种不同的状态,本节所有的内容都围绕这 6 种不同的状态进行的讲解,这也是本小节的核心内容,也是必须要掌握的内容。
相关文章:

11. Java线程的状态详解
1. 前言 本节内容主要是对多线程的 6 种状态进行详细讲解,具体内容点如下: 抛开语言,谈操作系统的线程的生命周期及线程 5 种状态,这是我们学习 Java 多线程 6 种状态的基础;掌握 Java 的线程生命周期及 6 种线程状态…...

ubuntu永久换镜像源详细方法
1.查看ubuntu的版本,不同的版本对应的不同的镜像源(下面会讲到,先按步骤操作即可) cat /etc/issue 2.先备份一个,防止更改错误 cp /etc/apt/sources.list /etc/apt/sources.list.backup 3.备份好之后删除原有的sour…...

docker部署(第一期)(相关命令)
腾讯云-----------镜像centOS 7.9 64位置---------------分配独立公网IP(远程连接)----------带宽选择最大-------------新建安全组-------------设置服务器密码---------WindTerm远程连接服务器 WindTerm下载:https://github.com/kingToolb…...

华为云L实例云服务器部署前后端分离项目全过程记录
1、配置云服务器 https://blog.csdn.net/modaoshi51991/article/details/139547630 2、上传前端项目并配置nginx 首先在前端项目运行以下代码将项目打包 我遇到node.js和openssl两个版本不兼容问题,更新版本依次解决即可 vue-cli-service build看一下package.json…...

uniapp - 微信小程序 - 自定义底部tabbar
废话不多说,直接行源码 这里需要的底部tabbar的图片在这里 我的资源里面呢 图片是这样的 先看成品吧 首先 - BaseApp\components\Tabbar.vue <script setup>import {ref,nextTick,watch} from "vue"// 核心 - 隐藏uniapp自带的底部tabbaruni.hi…...

每日一题——Python实现PAT乙级1030 完美数列(举一反三+思想解读+逐步优化)五千字好文
一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 初次尝试 再次尝试 代码结构 时间复杂度分析 空间复杂度分析 总结 我要更强 时…...

【C/C++】this指针的概念和作用
目录 一、this指针的概念 二、this指针的作用 2.1 访问当前对象的成员 2.2 返回对象本身 2.3 区分对象 2.4 在构造函数和析构函数中 2.5 在类的内部调用其他成员函数 2.6 作为参数传递 三、this指针使用 3.1 this指针的使用 3.2 C++ 中this指针使用 一、this…...

Spring Bean 的生命周期
在 Spring 框架中,Bean 的生命周期由 Spring 容器管理,从创建到销毁,Spring 提供了多种方式来定制 Bean 的初始化和销毁过程。本文将详细介绍 Spring Bean 的生命周期,包括 Bean 的初始化和销毁、自定义初始化方法和销毁方法。 一…...

锐起RDV5高性能云桌面
锐起是上海锐起信息技术有限公司旗下品牌。该公司创立于 2001 年,是桌面虚拟化产品和解决方案提供商,专注于桌面管理系统和私有云存储系统的系列软件产品研发,致力于简化 IT 管理、增强系统安全,提供简单、易用、稳定、安全的产品…...

pandas减少dataframe占用内存的若干方法
一、只获取文件需要的列,避免加载整个文件 举例:只获取A.B两列数据 df pd.read_csv(123.csv, usecols[A, B]) 二、使用更准确的数据类型,减少内存空间占用 import pandas as pd import numpy as np # 假设你的CSV文件有三列࿰…...

Ubuntu20.04 64位 安装docker(有问题可评论沟通交流)
1、查看系统版本 cat /proc/version 2、卸载可能存在或未安装成功的docker(新系统无需操作) apt-get remove docker docker-engine docker-ce docker.io 3、更新apt-get apt-get update 4、安装软件包允许apt-get通过 HTTPS 使用存储库 apt-get install …...

【C++PCL】点云处理Kd树和八叉树区别
作者:迅卓科技 简介:本人从事过多项点云项目,并且负责的项目均已得到好评! 公众号:迅卓科技,一个可以让您可以学习点云的好地方 重点:每个模块都有参数如何调试的讲解,即调试某个参数对结果的影响是什么,大家有问题可以评论哈,如果文章有错误的地方,欢迎来指出错误的…...

makefile学习过程
makefile 完美教程 - WittXie - 博客园 (cnblogs.com) Makefile教程(绝对经典,所有问题看这一篇足够了)-CSDN博客 Makefile入门(超详细一文读懂)-CSDN博客 最实用的Makefile教程 真的很简单(搞不明白网上的教程写那么复杂干嘛&…...

Kompas AI数据分析与预测功能对比
一、引言 在现代商业环境中,数据分析与预测是企业制定战略决策的关键工具。通过对大量数据的分析,企业能够识别趋势、预测未来变化,并做出更为明智的决策。本文将对比Kompas AI与其他主要AI产品在数据分析与预测方面的能力,展示K…...

Appium+python自动化(二十五)- 那些让人抓耳挠腮、揪头发和掉头发的事 - 获取控件ID(超详解)
简介 在前边的第二十二篇文章里,已经分享了通过获取控件的坐标点来获取点击事件的所需要的点击位置,那么还有没有其他方法来获取控件点击事件所需要的点击位置呢?答案是:Yes!因为在不同的大小屏幕的手机上获取控件的坐…...

【博士每天一篇文献-算法】Fearnet Brain-inspired model for incremental learning
阅读时间:2023-12-16 1 介绍 年份:2017 作者:Ronald Kemker,美国太空部队;Christopher Kanan,罗切斯特大学 期刊: arXiv preprint 引用量:520 Kemker R, Kanan C. Fearnet: Brain-…...

Appium+python自动化(二十六)- 烟花一瞬,昙花一现 -Toast提示(超详解)
简介 今天宏哥在这里首先给小伙伴们和童鞋们分享一个有关昙花的小典故:话说昙花原是一位花神,她每天都开花,四季都灿烂。她还爱上了每天给她浇水除草的年轻人。后来,此事给玉帝得知。于是,玉帝大发雷霆,要…...

大数据之路 读书笔记 Day1
大数据之路 读书笔记 Day1 阿里巴巴大数据系统体系架构图 1. 数据采集层 #mermaid-svg-YqqD2w3qV6jc2aGP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-YqqD2w3qV6jc2aGP .error-icon{fill:#552222;}#mermaid-sv…...

吴恩达揭秘:编程Agent如何革新软件开发行业
作为 AI 领域的杰出人物,吴恩达教授对编程 Agent 的兴起表示了极大的兴趣。他认为,编程 Agent 有潜力通过自动执行繁琐的任务、提高代码质量和加速开发周期来彻底改变软件开发行业。 本文将深入探讨吴恩达对编程 Agent 的见解, 多代理系统质…...

Study--Oracle-04-SQL练习
一、SQL语句思维导图 二、SQL练习 -- 以employee_id 为排序,列出前5个人 -- FETCH select employee_id,first_name from employees order by employee_id FETCH FIRST 5 rows only; -- 以employee_id 为排序,从第6个人开始 到第10个人 -- offset …...

目前音质最好的麦克风是哪款,一文读懂无线麦克风推荐哪些品牌好
在自媒体时代,无线领夹麦克风成为自媒体人不可或缺的助手。它帮助我们在各种环境中保持清晰声音,提升创作效率与作品质量。然而,面对众多无线麦克风产品,挑选一款性价比高、性能卓越的款式却成为难题。今天,我将分享…...

Python笔记 异常、模块与包
一、了解异常 异常的概念 什么是异常 当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的BUG。 二、异常的捕获 1.知道为什么要捕获异常 世界上没有完美的程…...

spark查看日志
Logger 当 Spark 任务已经提交到集群运行后,可以通过以下几种方式查看LoggerFactory输出的日志: Web 界面:在 Spark 任务运行时,可以通过访问 Spark 的 Web UI 来查看日志。通常,可以在浏览器中输入http://<drive…...

【LeetCode】每日一题:LRU缓存
请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类: LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存 int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 …...

记录一个Xshell使用中Xmanager...X11转发的提示问题
希望文章能给到你启发和灵感~ 如果觉得有帮助的话,点赞关注收藏支持一下博主哦~ 阅读指南 一、环境说明1.1 硬件环境1.2 软件环境 二、问题和错误三、解决四、理解和延伸一下 一、环境说明 考虑环境因素,大家适当的对比自己的软硬…...

Mamba 模型
建议观看讲解视频:AI大讲堂:革了Transformer的小命?专业拆解【Mamba模型】_哔哩哔哩_bilibili 1. 论文基本信息 2. 创新点 选择性 SSM,和扩展 Mamba 架构,是具有关键属性的完全循环模型,这使得它们适合作…...

30-33、SpringBoot项目部署\属性配置方式\多环境开发(一个文件)\多环境分组(多个文件)
1、打包插件:和springboot的版本保持一致 根pom <build><plugins><!--打包插件--><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>3.1.3</versi…...

【PyQt5】一文向您详细介绍 setContentsMargins() 的作用
【PyQt5】一文向您详细介绍 setContentsMargins() 的作用 下滑即可查看博客内容 🌈 欢迎莅临我的个人主页 👈这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地!🎇 🎓 博主简介:985高校的普通…...

分页查询前端对接
文章目录 添加角色修改角色当点击修改按钮后,那么就会弹出对话框,所以要设置显示为true点击修改的时候就是 要显示对话框 制作用户管理页面开发后端接口用户查询前端整合新增接口功能实现修改 添加角色 首先添加 添加表单的组件 那么总结一下 就是使用 组件 然后再使用变量接…...

从一万英尺外看libevent(源码刨析)
从一万英尺外看libevent 温馨提示:阅读时间大概二十分钟 前言 Libevent是用于编写高速可移植非阻塞IO应用的库,其设计目标是: 可移植性:使用libevent编写的程序应该可以在libevent支持的所有平台上工作。即使没有好的方式进行非…...