sleep和wait区别,并且查看线程运行状态

一、sleep和wait区别

区别一:语法使用不同

wait 方法必须配合 synchronized 一起使用,不然在运行时就会抛出 IllegalMonitorStateException 的异常

而 sleep 可以单独使用,无需配合 synchronized 一起使用。

区别二:所属类不同

wait 方法属于 Object 类的方法,而 sleep 属于 Thread 类的方法

区别三:唤醒方式不同

sleep 方法必须要传递一个超时时间的参数,且过了超时时间之后,线程会自动唤醒。而 wait 方法可以不传递任何参数,不传递任何参数时表示永久休眠,直到另一个线程调用了 notify 或 notifyAll 之后,休眠的线程才能被唤醒。也就是说 sleep 方法具有主动唤醒功能,而不传递任何参数的 wait 方法只能被动的被唤醒

区别四:释放锁资源不同

wait 方法会主动的释放锁,而 sleep 方法则不会。接下来我们使用代码的方式来演示一下二者的区别。

sleep 不释放锁

接下来使用 sleep 是线程休眠 2s,然后在另一个线程中尝试获取公共锁,如果能够获取到锁,则说明 sleep 在休眠时会释放锁,反之则说明不会释放锁,

在调用了 sleep 之后,在主线程里尝试获取锁却没有成功,只有 sleep 执行完之后释放了锁,主线程才正常的得到了锁,这说明 sleep 在休眠时并不会释放锁。

wait 释放锁

接下来使用同样的方式,将 sleep 替换成 wait,在线程休眠之后,在另一个线程中尝试获取锁,

当调用了 wait 之后,主线程立马尝试获取锁成功了,这就说明 wait 休眠时是释放锁的

区别五:线程进入状态不同

调用 sleep 方法线程会进入 TIMED_WAITING 有时限等待状态,而调用无参数的 wait 方法,线程会进入 WAITING 无时限等待状态。

总结

sleep 和 wait 都可以让线程进入休眠状态,并且它们都可以响应 interrupt 中断,但二者的区别主要体现在:语法使用不同、所属类不同、唤醒方式不同、释放锁不同和线程进入的状态不同。 ​

二、线程的状态Thread.State

三、供参考的多线程代码一、sleep和wait(WAITING和TIMED_WAITING状态)


public class Test04_ThreadState {public static void main(String[] args) {new Thread(new TimeWaiting(), "TimeWaitingThread").start();new Thread(new Waiting(), "WaitingThread").start();}/*** 该线程不断的进行睡眠*/static class TimeWaiting implements Runnable {@Overridepublic void run() {while (true) {SleepUtils.second(100);}}}/*** 该线程在Waiting.class实例上等待*/static class Waiting implements Runnable {@Overridepublic void run() {while (true) {synchronized (Waiting.class) {try {Waiting.class.wait();} catch (InterruptedException e) {e.printStackTrace();}}}}}}

四、查看线程运行状态的方法

1.jps

获得线程号和线程的类名

2.jstack + 线程号

jstack 2636

看线程某个时刻的运行情况(线程的快照)

这里打印出来的是当前线程的快照dump。

3.jvisualvm(可视化软件)

在java的jdk目录下的bin目录下有jvisualvm.exe文件,可以

打开软件后可以看到正在运行的进程,如下图

可以在其中找到java代码创建的线程的名字对应的线程

可以看到WatingThread线程状态是WAITING,等待状态

TimeWaitingThread线程状态是TIMED_WAITING,超时等待状态

和我们这篇文章的  二、线程的状态Thread.State  对应。

五、案例

一、Blocked阻塞状态

Blocked阻塞状态代码


public class Test04_ThreadState {public static void main(String[] args) {new Thread(new Blocked(), "BlockedThread-1").start();new Thread(new Blocked(), "BlockedThread-2").start();}/*** 该线程在Blocked.class实例上加锁后,不会释放该锁*/static class Blocked implements Runnable {@Overridepublic void run() {synchronized (Blocked.class) {while (true) {SleepUtils.second(100);}}}}
}

Blocked阻塞状态代码jvisualvm查看

由于BlockedThread-1先创建,抢占到了系统资源,运行后拿到了锁,并调用了sleep方法,因此进入TIMED_WAITING超时等待状态,而BlockedThread-2拿不到锁,因此进入Blocked阻塞状态。线程快照dump如下图:

Blocked阻塞状态代码总结

1.触发Blocked状态的原因

由于BlockedThread-1先创建,抢占到了系统资源,运行后拿到了锁,并调用了sleep方法,因此进入TIMED_WAITING超时等待状态,而BlockedThread-2拿不到锁,因此进入Blocked阻塞状态。

2.sleep方法

由于sleep方法不会释放锁,因此BlockedThread-2无法拿到锁,进入阻塞状态,更加验证了sleep方法不会释放锁。

二、ReentrantLock可重入锁

ReentrantLock可重入锁代码


public class Test04_ThreadState {private static Lock lock = new ReentrantLock();public static void main(String[] args) {new Thread(new Sync(), "SyncThread-1").start();new Thread(new Sync(), "SyncThread-2").start();}static class Sync implements Runnable {@Overridepublic void run() {lock.lock();try {SleepUtils.second(100);} finally {lock.unlock();}}}
}

ReentrantLock可重入锁代码jvisualvm查看

ReentrantLock可重入锁代码总结

1.synchronized和ReentrantLock区别(简略描述,之后会详细补充)

ReentrantLock锁更加面向对象
两个锁加锁之后另外一个线程进入状态不一样
synchronized进入blocked状态是被动的 还没有进入到同步代码块中
ReentrantLock是一种主动进入锁的状态 已经进入到代码块中 程序恢复之后 它会从等待的位置继续执行

最后总结:

        a.线程的状态 
            jps看线程的线程号
            jstack看线程某个时刻的运行情况(线程的快照)
            jvisualvm对线程进行dump

        b.线程调用sleep
            进入TimeWaiting状态 不会释放锁
        c.线程调用wait
            进入Waiting状态 会释放锁    
        d.A线程进入B线程已经拿到锁(synchronized)
            A线程会进入阻塞状态blocked状态
        e.当A线程进入B线程已经拿到锁(lock)
            A线程会进入等待状态waiting状态
        f.synchronized和lock区别
            1.lock锁更加面向对象
            2.两个锁加锁之后另外一个线程进入状态不一样:

                synchronized是blocked状态,lock是waiting状态
            3.synchronized进入blocked状态是被动的 还没有进入到同步代码块中
            4.lock是一种主动进入锁的状态 已经进入到代码块中 程序恢复之后 它会从等待的位置继续执行

如果你不太理解synchronized锁的对象是什么,你可以看下面这篇文章:

synchronized锁的对象是什么

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

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

相关文章

掌握iText:轻松处理PDF文档-高级篇-添加水印

前言 iText作为一个功能强大、灵活且广泛应用的PDF处理工具,在实际项目中发挥着重要作用。通过这些文章,读者可以深入了解如何利用iText进行PDF的创建、编辑、加密和提取文本等操作,为日常开发工作提供了宝贵的参考和指导。 掌握iText&…

【Apollo】ubuntu20.04源码安装apollo8.0

官方源码安装教程 https://blog.csdn.net/weixin_45929038/article/details/120113008 安装NVIDIA GPU驱动 Apollo 8.0 的一些模块的编译和运行需要依赖 NVIDIA GPU 环境(例如感知模块),如果有编译和运行这类模块的需求,则需要安…

蓝桥杯第一场强者挑战赛(C)SOSdp

之前在cf上面接触过SOSdp(子集dp),这里就碰到了。 思路: 异或运算即非进位加法运算,因此如果需要进位的话,那么就无法满足题意,因此条件弱化为不需要进位,也就是不存在同一位上面都是…

多维时序 | Matlab实现GA-LSTM-Attention遗传算法优化长短期记忆神经网络融合注意力机制多变量时间序列预测

多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测 目录 多维时序 | MATLAB实现BWO-CNN-BiGRU-Multihead-Attention多头注意力机制多变量时间序列预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 多维时序 | Matlab实…

Dubbo 的 go 语言实现迎来了 Dubbo3 版本

新版本的 dubbo-go: 全面升级 Triple 协议,兼容 gRPC、标准 HTTP 客户端,提供简单明了的 API 用于编写 RPC server 与 client,解决组件间的基本通信问题。 针对微服务场景,提供了完善的服务治理能力,这包括配置管理、可观测性、流量管控规则、生态集成与适配等的全面升级…

基于Python+WaveNet+MFCC+Tensorflow智能方言分类—深度学习算法应用(含全部工程源码)(一)

目录 前言引言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境Jupyter Notebook环境Pycharm 环境 相关其它博客工程源代码下载其它资料下载 前言 博主前段时间发布了一篇有关方言识别和分类模型训练的博客,在读者的反馈中发现许多小伙伴对方言…

Kubernetes(k8s)集群部署----->超详细

Kubernetes(k8s)集群部署----->超详细 一、资源准备二、安装准备2.1 主机环境设置2.1.1 关闭操作系统防火墙、selinux2.1.2 关闭swap交换分区2.1.3 允许iptables检测桥接流量(可选) 2.2 安装Docker环境2.3 安装Kubeadm…

idea__SpringBoot微服务10——整合JDBC(新依赖)

整合JDBC 完整项目地址:一、创建一个项目二、idea配置连接mysql三、创建yaml数据库连接配置文件四、测试一下,没有问题五、增删改查————————创作不易,如觉不错,随手点赞,关注,收藏(* ̄︶…

CS110L 系统编程安全 笔记

用户向程序输入数据,程序分析数据,但是当用户的输入大于缓冲区长度时,数据会溢出,覆盖掉内存中其他内容,比如函数返回地址,从而可能导致程序返回到错误的地址执行了不安全的程序(远程代码执行&a…

MySQL笔记-第10章_创建和管理表

视频链接:【MySQL数据库入门到大牛,mysql安装到优化,百科全书级,全网天花板】 文章目录 第10章_创建和管理表1. 基础知识1.1 一条数据存储的过程1.2 标识符命名规则1.3 MySQL中的数据类型 2. 创建和管理数据库2.1 创建数据库2.2 使…

Xcode编译速度慢是什么原因?如何提高编译速度?

Hello各位伙伴们好,我是咕噜铁蛋!作为一个开发者,我们都希望能够高效地开发应用程序,而编译速度是影响开发效率的重要因素之一。然而,有时候我们会发现在使用 Xcode 进行开发时,编译速度非常慢,…

模块一——双指针:11.盛最多水的容器

文章目录 题目解析算法原理解法一:暴力枚举(超时)解法二:双指针单调性 代码实现暴力枚举(超时)双指针单调性(时间复杂度为O(N),空间复杂度为O(1)) 题目解析 题目链接:11.盛最多水的容器 这道题…

C++的移动语义和完美转发

参考《现代C语言核心特性解析》 移动语义 C11新特性的std::move()用于将一个左值转换为右值引用。它并不是实际移动或复制数据,而是通过将一个左值强制转换为一个右值引用来实现对对象的转移。这个特性在C11中引入,用于优化对象移动操作的效率。 我们…

万界星空科技电子装配行业MES解决方案

电子电器装配属于劳动密集型、科技含量较高的行业,产品零部件种类繁多,生产组装困难,生产过程存在盲点,同时也决定了生产流水线多且对自动化水平要求较高。 万界星空科技提供的电子行业MES解决方案,提供从仓储管理、生…

pytorch——房价预测

1、首先对数据进行读取和预处理 2、读取数据后,对x数据进行标准化处理,以便于后续训练的稳定性,并转换为tensor格式 3、接下来设置训练参数和模型 这里采用回归模型,既yx*weight1bias1,设置的学习率为0.0006&#x…

perl脚本中使用eval函数执行可能有异常的操作

perl脚本中有时候执行的操作可能会引发异常&#xff0c;为了直观的说明&#xff0c;这里举一个json反序列化的例子&#xff0c;脚本如下&#xff1a; #! /usr/bin/perl use v5.14; use JSON; use Data::Dumper;# 读取json字符串数据 my $json_str join(, <DATA>); # 反…

《地理信息系统原理》笔记/期末复习资料(12. 地理信息工程)

目录 12. 地理信息工程 12.1. 地理信息系统工程的概念 12.2. 地理信息系统工程建设过程 12.2.1. 应用型地理信息系统设计步骤和方法 12.2.2. 需求分析 12.2.3. 系统设计 12.2.4. 系统开发与实施 12.2.5. 系统的评价和维护 12.3. GIS标准 12.4. 习题 12. 地理信息工程…

CNN、LeNet、AlexNet基于MNIST数据集进行训练和测试,并可视化对比结果

完成内容&#xff1a; 构建CNN并基于MNIST数据集进行训练和测试构建LeNet并基于MNIST数据集进行训练和测试构建AlexNet并基于MNIST数据集进行训练和测试对比了不同网络在MNIST数据集上训练的效果 准备工作 import torch import torch.nn as nn import torch.optim as optim …

高通SDX12:nand flash适配

一、SBL阶段 代码流程如下: boot_images\core\storage\flash\src\dal\flash_nand_init.c nand_probe ->nand_intialize_primary_hal_device ->>nand_get_device_list_supportedboot_images\core\storage\flash\src\dal\flash_nand_config.c ->>>flash_n…

ue4 解决角度万向锁的问题 蓝图节点

问题&#xff1a;当角度值从359-1变化的时候&#xff0c;数值会经历358、357… 解决方法&#xff1a;勾上Shortest Path&#xff0c;角度值的会从359-1