线程生命周期及五种状态
文章目录
- 一、线程生命周期及五种状态
- 1、New(初始化状态)
- 2、Runnable(就绪状态)
- 3、Running(运行状态)
- 4、Blocked(阻塞状态)
- 5、Terminated(终止状态)
- 二、线程基本方法
- 1、线程等待(wait)
- 2、线程睡眠(sleep)
- 3、线程让步(yield)
- 4、线程中断(interrupt)
- 5、join(等待其他线程终止)
- 6、线程唤醒(notify)
- 7、其他方法
- 三、重点面试问题
- 1、sleep和wait的区别:
- 2、wait()、notify() 释放锁问题:
⭐️最全线程知识汇总篇(线程生命周期、线程池创建、线程池实现原理、线程基本方法)⭐️
⭐️ 如何创建一个线程?
⭐️ Java多线程之Executor框架
⭐️ 多线程分批处理数据
一、线程生命周期及五种状态
1、New(初始化状态)
用new语句创建的线程处于新建状态,此时它和其他Java对象一样,仅仅在堆区中被分配了内存。如:Thread t = new MyThread();
2、Runnable(就绪状态)
当调用线程对象的start()方法,线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,Java虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得CPU的使用权,并不是说执行了start()此线程立即就会执行。
3、Running(运行状态)
当就绪状态中的线程获得了CUP执行资源,执行run()中的代码,这样的线程我们称为运行状态的线程。
4、Blocked(阻塞状态)
处于运行中的线程,由于某种原因放弃对cpu的使用权,处于阻塞状态,直到其进入就绪状态,才有机会再次被cpu调用进入运行状态。
根据阻塞原因不同,阻塞分为三种
:
-
等待阻塞:运行状态中的线程执行wait方法,进入等待队列,等待阻塞;Java虚拟机就会把线程放到这个对象的等待池中;
-
同步阻塞:线程获取同步锁失败(因为锁被其他线程占用),Java虚拟机就会把这个线程放到这个对象的锁池中;
-
其他阻塞:通过调用sleep方法或者join方法或者发出I/O请求时,线程会进入阻塞状态,当sleep()状态超时,或者join()等待线程终止或者超时,或者I/O处理完毕,线程重新转入就绪状态;
5、Terminated(终止状态)
-
正常结束,线程执行完
-
异常退出
异常退出,除了程序有问题导致的异常的退出,还可以使用共享变量的方式(定义个boolean标识等)退出,或者Interrupt中断线程,抛出异常,捕获异常break,跳出循环状态; -
调用stop(),会造成死锁,线程不安全,不建议使用
二、线程基本方法
1、线程等待(wait)
调用该方法,线程进入waiting状态,只有等待另外的线程通知或被中断才会返回,调用wait()后,会释放对象锁,因为wait方法一般用在同步方法或者同步代码块中。
2、线程睡眠(sleep)
强迫一线程睡 N毫秒,sleep不会释放当前锁,导致线程进入Timed-wating状态。
3、线程让步(yield)
yeild会使当前线程让出cpu执行时间片,与其他线程一起重新竞争cpu时间片,一般情况下,优先级高的先得到,但也不一定,有的系统对优先级不敏感。
4、线程中断(interrupt)
调用一个线程的interrupt() 方法中断一个线程,并不是强行关闭这个线程,仅仅是改变了内部维护的中断标识位,是线程固有的一个标识位。可以调用
在run内部根据thread.isIterrupted() 安全终止线程。
static方法isIterrupted() 判定当前线程是否处于中断状态:
1)如果一个正常线程,调用interrupt() ,是不能被打断的,打印中断标志位置为true;
public class TestIterruptedDemo1{public static void main (string[] args)throws InterruptedException {//创建线程t1Thread t1=new Thread (()->if(Thread.currentThread.isInterrupted()){log.dubug("---------t1中断标识true,进来了---------"); }},name:"t1");t1.start();t1.interrupt();//没等t1启动,主线程先执行打断t1,将表示设置为true }
}
t1还没有启动,主线程便执行了一个打断,即打断一个正常线程,则打印结果为true,将线程标记设置为true:
控制台打印:
---------t1中断标识true,进来了---------"
2)如果一个sleep或者wait的线程,调用interrupt() ,方法则抛出InterruptedException( InterruptedException表示一个阻塞被中断了),线程的中断标志位会被复位成false;相当于用异常响应了这个中断,所以释放中断标志位。
public class TestIterruptedDemo2{public static void main (string[] args)throws InterruptedException {//创建线程t1Thread t1=new Thread (()->try {log.dubug("---------t1启动,然后sleep---------"); TimeUnit.SECONDS.sleep(timeout:200); } catch (InterruptedException e) {log.dubug("---------t1被主线程打断了---------"); e.printStackTrace();} },name:"t1");t1.start();//主线程睡一下,主要是为了确保t1先执行,然后再打断sleep的t1TimeUnit.SECONDS.sleep(timeout:1); t1.interrupt();//主线程1秒后醒来,打断t1 log.dubug("---------t1的打断标识是{}---------",t1.isInterrupted()); }
}
控制台打印:
---------t1启动,然后sleep---------
---------t1被主线程打断了---------
---------t1的打断标识是false---------
5、join(等待其他线程终止)
当前线程调用join(),则线程转为阻塞状态,eg:A线程中插入了B.join(),则B先执行,执行完,A线程继续执行;常见的是主线程生成并启动了子线程,需要用到子线程返回结果的场景;
6、线程唤醒(notify)
Object类中的notify唤醒在此对象监视器上等待的单个线程;
notifyAll唤醒在此对象监视器上等待的所有线程;
7、其他方法
- isAlive判断一个线程是否存活;
- activeCount 程序中活跃的线程数;
- currentThread得到当前线程;
- setPriority设置一个线程的优先级;
- getPriority获取一个线程的优先级;
- isDaemon线程是否为守护线程;
小结
:方法wait(), notify()和notifyAll()被定义在Object 类里;
Thread类的sleep()和yield ()方法是静态的;
wait(), notify()和notifyAll ()必须在同步方法或者同步块中被调用
三、重点面试问题
1、sleep和wait的区别:
sleep属于Thread类,让出cpu,但是监控状态依然保持者,指定时间到了,就会恢复运行;
wait属于Object类方法,释放对象锁,进入等待锁定池,需要notify()才能重新进入运行状态;
2、wait()、notify() 释放锁问题:
wait()会立刻释放synchronized(obj)中的obj锁,以便其他线程可以执行obj.notify()
但是notify()不会立刻立刻释放sycronized(obj)中的obj锁,必须要等notify()所在线程执行完synchronized(obj)块中的所有代码才会释放这把锁.yield(),sleep()不会释放锁。
相关文章:

线程生命周期及五种状态
文章目录一、线程生命周期及五种状态1、New(初始化状态)2、Runnable(就绪状态)3、Running(运行状态)4、Blocked(阻塞状态)5、Terminated(终止状态)二、线程基本方法1、线程等待(wait)2、线程睡眠(sleep)3、…...
OBCP第八章 OB运维、监控与异常处理-灾难恢复
灾难恢复是指当数据库中的数据在被有意或无意破坏后复原数据库所需要执行的活动 回收站:回收站在原理上说就是一个数据字典表,放置用户删除的数据库对象信息。用户删除的东西被放入回收站后,其实仍然占据着物理空间,除非您手动进…...

亚马逊云科技Serverless Data:数字经济下的创新动能
Serverless时代已经到来!企业的技术架构,总是伴随着不断增长的数据与日趋复杂的业务持续演进。如何通过构建更易用的技术架构来聚焦在业务本身,而不必在底层基础设施的管理上投入过多的精力,是数据驱动型企业需要思考的重要议题。…...
【Ruby学习笔记】15.Ruby 异常
Ruby 异常 异常和执行总是被联系在一起。如果您打开一个不存在的文件,且没有恰当地处理这种情况,那么您的程序则被认为是低质量的。 如果异常发生,则程序停止。异常用于处理各种类型的错误,这些错误可能在程序执行期间发生&…...

聊聊MySQL主从延迟
文章目录 MySQL 的高可用是如何实现的呢?二、什么是主备延迟?三、主备延迟常见原因1、备库机器配置差2、备库干私活3、大事务四、主库不可用,主备切换有哪些策略?1、可靠优先2、可用优先实验一实验二3、结论MySQL 的高可用是如何实现的呢? 高可用性(high availability,缩…...
【C++从0到1】19、C++中多条件的if语句
C从0到1全系列教程 1、多条件的if语句 语法: if (表达式一) { // 表达式一为真时执行的语句。 } else if (表达式二) {// 表达式二为真时执行的语句。 } else if (表达式三) {// 表达式三为真时执行的语句。 } …… else if (表达式n) {// 表达式n为真时执行的语句。…...

【多微电网】计及碳排放的基于交替方向乘子法(ADMM)的多微网电能交互分布式运行策略研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

Linux(centos7)安装防火墙firewalld及开放端口相关命令
安装firewalld 防火墙命令: yum install firewalld 安装完成,查看防火墙状态为 not running,即未运行,输入命令开启: 添加开放端口: 防火墙相关命令: 查看防火墙状态 systemctl status firewa…...

Linux部署.Net Core Web项目
本文主要记录我在Linux(Ubuntu)上部署.net core 的操作记录,也便于以后部署。 如对您有所帮助,不胜荣幸~ 文章目录前言一、准备工作1. 版本信息2. windows端web项目二、操作步骤1. Linux 配置 .net 运行环境1.1 查看最新 .net 运行环境的下载路径1.2 安装…...

【C++】STL之stack、queue的使用和模拟实现+优先级队列(附仿函数)+容器适配器详解
之前的一段时间,我们共同学习了STL中一些容器,如string、vector和list等等。本章我们将步入新阶段的学习——容器适配器。本章将详解stack、queue的使用和模拟实现优先级队列(附仿函数)容器适配器等。 目录 (一&…...

第⑦讲:Ceph集群RGW对象存储核心概念及部署使用
文章目录1.RadosGW对象存储核心概念1.1.什么是RadosGW对象存储1.2.RGW对象存储架构1.3.RGW对象存储的特点1.4.对象存储中Bucket的特性1.4.不同接口类型的对象存储访问对比2.在集群中部署RadosGW对象存储组件2.1.部署RGW组件2.2.集群中部署完RGW组件后观察集群的信息状态2.3.修改…...

从异步到promise
一,背景 1.1,js的单线程 这一切,要从js诞生之初说起,因为js是单线程的语言。 js单线程原因:作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程&…...

Linux系统中进行JDK环境的部署
一、为什么需要部署JDK。 JDK:Java Development Kit,是用于Java语言开发的环境。 部署JDK不需要懂得Java语言,只需要掌握Linux相关命令即可。 二、部署版本与环境。 系统:安装在VMware环境下的CentOS7.6; JDK版本&a…...
Leetcode.1033 移动石子直到连续
题目链接 Leetcode.1033 移动石子直到连续 Rating : 1421 题目描述 三枚石子放置在数轴上,位置分别为 a,b,c。 每一回合,你可以从两端之一拿起一枚石子(位置最大或最小),并将其放入…...
【Java】在SpringBoot中使用事务注解(@Transactional)时需要注意的点
在SpringBoot中使用事务注解(Transactional)时需要注意的点Transactional是什么使用事务注解(Transactional)时需要注意的点Transactional是什么 Transactional是Spring框架提供的一个注解,用于声明事务边界和配置事务…...

找到序列最高位的1和最高位的0并输出位置
前言: 该题为睿思芯科笔试题,笔试时长20分钟。 题目描述 接口如下: module first_1_and_0#(parameter WIDTH 8 )(input [WIDTH-1:0] data_in ,input target ,output exist ,outpu…...
面试总结sdiugiho
一、进程与线程的区别 进程: 一个在内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程可以有多个线程; windows 任务管理器中 一个 exe 就是一个进程。 线程: 进程中的一个执行任务(控制…...

WIN10無法再使用 IE 瀏覽器打开网页解决办法
修改 Registry(只適用 Win10) 微軟已於 2023 年 2 月 14 日永久停用 Internet Explorer,會透過 Edge 的更新讓使用者開啟 IE 時自動導向 Edge,其餘如工作列上的圖示,使用的方法則是透過「品質更新」的 B 更新來達成&am…...

搭建SpringBoot和Mysql Demo
1. 引言 在上一篇文章中,介绍了如何搭建一个SpringBoot项目;本篇文章,在上一篇文章的基础上,接着介绍下怎样实现SpringBoot和MySQL的整合。在后端开发中,数据库开发是绕不开的话题,开发中很多的时间都是在…...

晶振03——晶振烧坏的原因
晶振03——晶振烧坏的原因 首先要清楚的一件事情是:晶振分为无源晶振与有源晶振两大类。基于这两类晶振的内部结构与工作原理的差异,晶振被烧坏的情况也要分为两大类: 针对无源晶振被烧坏的情况有以下两点: 1、手焊操作不当 假…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...

无法与IP建立连接,未能下载VSCode服务器
如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...

如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...