java线程状态

图形说明:
在这里插入图片描述
Thread.State源码注释:

public enum State {/***  新生状态:线程对象创建,但是还未start()*/NEW,/*** 线程处于可运行状态,但是这个可运行状态并不代表线程一定在虚拟机中执行。* 需要等待从操作系统获取到资源(比如处理器时间片),才能真正的去运行*/RUNNABLE,/*** 当前线程处于阻塞状态,正在等待另一个线程的monitor lock释放,才进入synchronized代码块或方法*/BLOCKED,/*** 调用Object#wait() 、 Thread.join方法后当前线程处于等待状态,* 等待其他的线程执行特定的动作,才能从等待状态退出。* 比如:Object.wait()的线程需要等待其他线程调用Object.notify()、Object.notifyAll()才能退出* 比如:调用了Thread.join()的线程需要等待指定的线程执行完成才能退出等待状态。*/WAITING,/*** 进入特定时间内的等待状态,等待一段指定的时间sleep(timed)、wait(timed)或者等待Thread.join(timed)的时间.* 到达指定时间点自动退出恢复到RUNNABLE状态*/TIMED_WAITING,/*** 线程结束状态*/TERMINATED;
}

代码示例:
NEW状态:

public class ThreadState {public static void main(String[] args) throws Exception {Thread thread = new Thread();System.out.println(thread.getState());}
}

结果:
在这里插入图片描述

RUNNABLE状态:

public static void main(String[] args) throws Exception {Thread thread = new Thread(()-> {while (true){Thread.yield();}});thread.start();Thread.sleep(2000);System.out.println(thread.getState());}
}

结果:
在这里插入图片描述

WAITING状态:

public static void main(String[] args) throws Exception {Thread thread = new Thread(()-> {LockSupport.park();while (true){Thread.yield();}});thread.start();Thread.sleep(50);System.out.println(thread.getState());LockSupport.unpark(thread);Thread.sleep(50);System.out.println(thread.getState());}

结果:
在这里插入图片描述
join方法代码:
在这里插入图片描述
可见Thread#join()是在线程实例存活的时候总是调用Object#wait()方法,也就是必须在线程执行完毕isAlive()为false(意味着线程生命周期已经终结)的时候才会解除阻塞。

TIMED WAITING状态:

public static void main(String[] args) throws Exception {Thread thread = new Thread(()-> {try {Thread.sleep(1000);} catch (InterruptedException e) {//ignore}});thread.start();thread.notify();Thread.sleep(50);System.out.println(thread.getState());Thread.sleep(1000);System.out.println(thread.getState());}

结果:
在这里插入图片描述
BLOCKED状态:
BLOCKED状态也就是阻塞状态,该状态下的线程不会被分配CPU执行时间。线程的状态为BLOCKED的时候有两种可能的情况:

A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method

1.线程正在等待一个监视器锁,只有获取监视器锁之后才能进入synchronized代码块或者synchronized方法,
在此等待获取锁的过程线程都处于阻塞状态。

reenter a synchronized block/method after calling Object#wait()

2.线程X步入synchronized代码块或者synchronized方法后(此时已经释放监视器锁)调用Object#wait()方法之后进行阻塞,
当接收其他线程T调用该锁对象Object#notify()/notifyAll(),但是线程T尚未退出它所在的synchronized代码块或者synchronized方法,
那么线程X依然处于阻塞状态(注意API注释中的reenter,理解它场景2就豁然开朗)。
private static final Object MONITOR = new Object();private static final DateTimeFormatter F = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");public static void main(String[] args) throws Exception {System.out.printf("[%s]-begin...%n", F.format(LocalDateTime.now()));Thread thread1 = new Thread(() -> {synchronized (MONITOR) {System.out.printf("[%s]-thread1 got monitor lock...%n", F.format(LocalDateTime.now()));try {Thread.sleep(1000);MONITOR.wait();} catch (InterruptedException e) {//ignore}System.out.printf("[%s]-thread1 exit waiting...%n", F.format(LocalDateTime.now()));}});Thread thread2 = new Thread(() -> {synchronized (MONITOR) {System.out.printf("[%s]-thread2 got monitor lock...%n", F.format(LocalDateTime.now()));try {MONITOR.notify();//这个时候thread2已经释放了MONITOR锁,thread1已经被唤醒,但是因为thread2还在占用MONITOR,所以thread1是blocked状态//对应 reenter a synchronized block/method after calling Object#wait()Thread.sleep(2000);} catch (InterruptedException e) {//ignore}System.out.printf("[%s]-thread2 releases monitor lock...%n", F.format(LocalDateTime.now()));}});thread1.start();thread2.start();// 这里故意让主线程sleep 1500毫秒从而让thread2调用了Object#notify()并且尚未退出同步代码块,确保thread1调用了Object#wait()Thread.sleep(1500);  System.out.println(thread1.getState());System.out.printf("[%s]-end...%n", F.format(LocalDateTime.now()));}

结果:
在这里插入图片描述
源码的注释说的就是上述测试的情况,虽然调用了notify方法,但是被唤醒的线程并不会进入RUNNABLE状态,需要等thread2释放锁以后重新参与锁竞争;
在这里插入图片描述

TERMINATED状态:

public static void main(String[] args) throws Exception {Thread thread = new Thread(() -> {});thread.start();Thread.sleep(50);System.out.println(thread.getState());}

结果:
在这里插入图片描述

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

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

相关文章

Spark-Core核心算子

文章目录 一、数据源获取1、从集合中获取2、从外部存储系统创建3、从其它RDD中创建4、分区规则—load数据时 二、转换算子(Transformation)1、Value类型1.1 map()_1.2 mapPartitions()1.3 mapPartitionsWithIndex(不常用)1.4 filterMap()_扁平化(合并流)…

Java面试之斐波那契数列(Fibonacci)及其应用:青蛙跳台阶问题

文章目录 一、斐波那契数列问题1.1 题目1.2 什么是斐波那契数列1.3 效率很低的解法:递归1.4 递归缺点分析 二、比较好的解决办法2.1 保存数列中间项2.2 从下往上计算 三、公式法四、青蛙跳台阶问题4.1 题目及分析4.2 代码实现 一、斐波那契数列问题 1.1 题目 写一…

Paddle训练COCO-stuff数据集学习记录

COCO-stuff数据集 COCO-Stuff数据集对COCO数据集中全部164K图片做了像素级的标注。 80 thing classes, 91 stuff classes and 1 class ‘unlabeled’ 数据集下载 wget --directory-prefixdownloads http://images.cocodataset.org/zips/train2017.zip wget --directory-prefi…

XXL-JOB 分布式任务调度平台

目录 背景 项目架构 核心流程1——执行器自动注册 核心流程2——调度任务 特性——分片广播 背景 为什么需要任务调度平台? 单机定时任务 Java中传统的定时任务实现方案,比如JDK 1.3 提供的 Timer、JDK 1.5 提供的 ScheduledExecutorService、Spring 3.0 提…

huggingface下载模型文件(基础入门版)

huggingface是一个网站,类似于github,上面拥有众多开源的模型、数据集等资料,人工智能爱好者可以很方便的上面获取需要的数据,也可以上传训练好的模型,制作的数据集等。本文只介绍下载模型的方法,适合新手入…

win | wireshark | 在win上跑lua脚本 解析数据包

前提说明:之前是在linux 系统上配置的,然后现在 在配置lua 脚本 ,然后 分析指定协议 的 数据包 其实流程也比较简单,但 逻辑需要缕清来 首先要把你 预先准备的 xxx.lua 文件放到wireshark 的安装文件中,(我…

deque容器

1 deque容器基本概念 功能: 双端数组,可以对头端进行插入删除操作 deque与vector区别: vector对于头部的插入删除效率低,数据量越大,效率越低deque相对而言,对头部的插入删除速度回比vector快vector访问…

python实现MQTT协议(发布者,订阅者,topic)

python实现MQTT协议 一、简介 1.1 概述 本文章针对物联网MQTT协议完成python实现 1.2 环境 Apache-apollo创建brokerPython实现发布者和订阅者 1.3 内容 MQTT协议架构说明 : 利用仿真服务体会 MQTT协议 针对MQTT协议进行测试 任务1:MQTT协议应…

maven搭建spring项目

前提 安装jdk 安装maven 安装eclipse 创建maven项目 搭建spring项目 pom.xml <dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.4.RELEASE</version> </dependency&…

【java 入侵 C# 之路】1-入门

感谢 https://www.cnblogs.com/mww-NOTCOPY/p/12213373.html 百度百科 jvm对应clr java se runtime对应 .net framework&#xff0c; jdk对应 .net framework sdk&#xff0c; java对应C# .NET 是开发者平台&#xff0c;它包含开发环境、技术框架、社区论坛、服务支持等&…

学习pytorch8 土堆说卷积操作

土堆说卷积操作 官网debug torch版本只有nn 没有nn.functional代码执行结果 B站小土堆视频学习笔记 官网 https://pytorch.org/docs/stable/nn.html#convolution-layers 常用torch.nn, nn是对nn.functional的封装&#xff0c;使函数更易用。 卷积核从输入图像左上角&#xf…

Bito使用手册

第一步&#xff1a;输入网站 https://alpha.bito.co/bitoai/ 第二步&#xff1a;填写邮箱 第三步&#xff1a;登录邮箱&#xff0c;获取验证码 第四步&#xff1a;填写验证码 第五步&#xff1a;完成

【LeetCode-中等题】994. 腐烂的橘子

文章目录 题目方法一&#xff1a;bfs层序遍历 题目 该题值推荐用bfs&#xff0c;因为是一层一层的感染&#xff0c;而不是一条线走到底的那种&#xff0c;所以深度优先搜索不适合 方法一&#xff1a;bfs层序遍历 广度优先搜索&#xff0c;就是从起点出发&#xff0c;每次都尝…

UG\NX CAM二次开发 查询工序所在的几何组TAG UF_OPER_ask_geom_group

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 查询工序所在的几何组TAG UF_OPER_ask_geom_group 效果: 代码: void MyClass::do_it() { int count=0;tag_t * objects;UF_UI_ONT_ask_selected_nodes(&count, &objects);for (in…

linux 下安装配置nexus

一、安装包获取方式 方式一 1、直接把下载好的安装包上传到服务器中 方式二 2、通过wget安装Nexus压缩包 ①、可以使用以下命令进行安装Nexus的最新版本 wget https://download.sonatype.com/nexus/3/latest-unix.tar.gz②、也可以点击官网复制想要下载的Nexus压缩包进行安装…

【Linux系列】离线安装openjdk17的rpm包

首发博客地址 首发博客地址[1] 系列文章地址[2] 视频地址[3] 准备 RPM 包 请从官网下载&#xff1a;https://www.oracle.com/java/technologies/downloads/#java17[4] 如需不限速下载&#xff0c;请关注【程序员朱永胜】并回复 1020 获取。 安装 yum localinstall jdk-17_linux…

C++智能指针之weak_ptr(保姆级教学)

目录 C智能指针之weak_ptr 概述 作用 本文涉及的所有程序 使用说明 weak_ptr的常规操作 lock(); use_count(); expired(); reset(); shared_ptr & weak_ptr 尺寸 智能指针结构框架 常见使用问题 shared_ptr多次引用同一数据&#xff0c;会导致两次释放同一内…

没有使用sniffer dongle在windows抓包蓝牙方法分享

网上很多文章都是介绍买一个sniffer dongle来抓蓝牙数据,嫌麻烦又费钱,目前找到一个好方法,不需要sniffer就可以抓蓝牙数据过程,现分享如下: (1)在我资源附件找到相关安装包或者查看如下链接 https://learn.microsoft.com/zh-cn/windows-hardware/drivers/bluetooth/testing-bt…

【Python】批量下载页面资源

【背景】 有一些非常不错的资源网站,比如一些MP3资源网站。资源很丰富,但是每一个资源都不大,一个一个下载费时费力,想用Python快速实现可复用的批量下载程序。 【思路】 获得包含资源链接的静态页面,用beautifulsoup分析页面,获得所有MP3资源的实际地址,然后下载。…

安卓逆向 - Frida反调试绕过

本文仅供学习交流&#xff0c;只提供关键思路不会给出完整代码&#xff0c;严禁用于非法用途&#xff0c;谢绝转载&#xff0c;若有侵权请联系我删除&#xff01; 本文案例 app&#xff1a;5Lqs5LicYXBwMTEuMy4y 一、引言&#xff1a; Frida是非常优秀的一款 Hook框架&#…