java基础系列(六) sleep()和wait() 区别

news/2024/4/27 6:31:00/文章来源:https://blog.csdn.net/u012514113/article/details/129224783

一.前言

        关于并发编程这块, 线程的一些基础知识我们得搞明白, 本篇文章来说一下这两个方法的区别,对Android中的HandlerThread机制原理可以有更深的理解, HandlerThread源码理解,请查看笔者的这篇博客:

HandlerThread源码理解_handlerthread 源码_broadview_java的博客-CSDN博客

二.区别

2.1 sleep方法

public static native void sleep(long millis)方法是Thread的静态方法,很显然它是让当前线程按照指定的时间休眠,其休眠时间的精度取决于处理器的计时器和调度器。需要注意的是如果当前线程获得了锁,sleep方法并不会失去锁

Thread类中的静态方法sleep(),当一个执行中的线程调用了Thread的sleep()方法后,调用线程会暂时让出时间的执行权,这期间不参与cpu的调度,但是该线程持有的锁是不让出的。时间到了会正常返回,线程处于就绪状态,然后参与cpu调度,获取到cpu资源之后就可以运行。

我们通过这个Demo来看下

public class SleepTest {private static Object lock = new Object();public static void main(String[] args) {new Thread(()->{synchronized (lock) {System.out.println("线程A休眠10秒不放弃锁");try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("A休眠10秒醒来");}}).start();new Thread(()->{synchronized (lock){System.out.println("线程B休眠5秒不放弃锁");try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("B休眠5秒醒来");}}).start();}
}

打印结果如下:

线程A休眠10秒不放弃锁
A休眠10秒醒来
线程B休眠5秒不放弃锁
B休眠5秒醒来

线程B休眠5秒不放弃锁
B休眠5秒醒来
线程A休眠10秒不放弃锁
A休眠10秒醒来

解释如下:

无论执行多少次,都是先A输出再B输出 或者 先B输出再A输出,不会出现交叉输出的情况,
因为A获取到锁之后,即使是sleep也不会释放锁,因B获取不到锁,也就无法执行。

总结:  sleep方法不会释放锁

2.2 wait方法

Object.wait方法会释放锁对象

一个调用了某个对象的 Object.wait 方法的线程会等待另一个线程调用此对象的 Object.notify()方法 或 Object.notifyAll()方法。

其实waiting状态并不是一个线程的操作,它体现的是多个线程间的通信,可以理解为多个线程之间的协作关系, 也是java并发编程要处理的核心问题.

当多个线程协作时,比如A,B线程,如果A线程在Runnable(可运行)状态中调用了wait()方法那么A线程就进入了Waiting(无限等待)状态,同时失去了同步锁。

假如这个时候B线程获取到了同步锁,在运行状态中调用了notify()方法,那么就会将无限等待的A线程唤醒。

注意是唤醒,如果获取到锁对象,那么A线程唤醒后就进入Runnable(可运行)状态;如果没有获取锁对象,那么就进入到Blocked(锁阻塞状态)。
 

我们来看这个Demo :

public class wakeLockTest {private static Object lock = new Object(); public static void main(String[] args) {Thread thread1 = new Thread(new Runnable1(), "线程1");thread1.start();Thread thread2 = new Thread(new Runnable2(), "线程2");thread2.start();}static class Runnable1 implements Runnable{@Overridepublic void run() {synchronized (lock) {try {lock.wait();System.out.println("当前线程名: "+Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}}}}static class Runnable2 implements Runnable{@Overridepublic void run() {synchronized (lock) {lock.notify();System.out.println("当前线程名: "+Thread.currentThread().getName());}}}
}

如果不加同步锁相关的代码,   从代码流程来看, 线程1 先执行, 线程2再执行,肯定会打印

当前线程名: 线程1
当前线程名: 线程2

加入锁相关的代码后,打印如下:

三. 总结


sleep()方法是Thread类的方法,线程通过调用该方法,进入休眠状态主动让出CPU,从而CPU可以执行其他的线程。经过sleep指定的时间后,CPU回到这个线程上继续往下执行。

如何当前线程进入了同步锁,sleep()方法并不会释放锁。即使当前线程使用sleep方法让出了cpu,但其他被同步锁挡住了的线程也无法得到执行。

使用场合:
线程的调度执行是按照其优先级的高低顺序进行的,当高级别的线程未死亡时,低级别的线程没有机会获得CPU资源。有时优先级高的线程需要优先级低的线程完成一些辅助工作或者优先级高的线程需要完成一些比较费时的工作,此时优先级高的线程应该让出CPU资源,使得优先级低的线程有机会执行。为了达到这个目的,优先级高的线程可以在自己的run()方法中调用sleep方法来使自己放弃CPU资源,休眠一段时间。

wait()方法

Obj.wait(),与Obj.notify()必须要与synchronized(Obj)一起使用,也就是wait,与notify是针对已经获取了Obj锁进行操作,从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内

从功能上来说wait就是说线程在获取对象锁后,主动释放对象锁,同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程,才能继续获取对象锁,并继续执行。

相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后,并不是马上就释放对象锁的,而是在相应的synchronized(){}语句块执行结束后,才会释放锁.
 

两者区别
1.sleep()方法,属于Thread类的。; wait()方法,则是属于Object类的;
2.sleep方法不会释放锁,而wait方法会释放锁
3.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
4.sleep可以自然醒,wait必须等待被唤醒.


 


 

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

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

相关文章

安装kibana 报错/访问不了

安装kibana 报错1,elasticsearch.yaml 和kibana.yaml 配置问题2,elasticsearch 和kibana版本不一致3,索引问题1,elasticsearch.yaml 和kibana.yaml 配置问题 我的RPM安装的,配置文件都在/etc/ vim /etc/elasticsearc…

【Python基础】类

面向对象编程 面向对象编程是最有效的软件编写方法之一。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术发展到一定阶段后的产物。 面向对象和面向过程的区别 比如我想吃西红柿炒蛋,怎么运用面向过程的方法来解决这个问题呢?…

《高性能MySQL》——MySQL基准测试(笔记)

文章目录二、MySQL基准测试2.1 为什么需要基准测试2.2 基准测试的策略2.2.1 测试何种指标2.3 基准测试方法2.3.1设计和规划基准测试2.3.2 基准测试应该运行多长时间2.3.3 获取系统性能和状态2.3.4 获得准确的测试结果2.3.5 运行基准测试并分析结果2.3.6 绘图的重要性2.4 基准测…

yii-shopwind商城多数页面报错,修改mysql一个配置就解决!

解决办法打开mysql配置文件,在[mysqld]下添加如下一行:sql_modeNO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES成功解决!还以为是网站的代码问题, 惊讶到我了. 开源网站下载下来就报错 多不可思议. 终于是配置的问题!加油报错信息如下是其中一个界面的&…

[MySQL]MySQL数据类型

文章目录数据类型分类数值类型tinyint类型bit类型float类型decimal类型字符串类型char类型varchar类型char和varchar对比日期和时间类型enum和set类型数据类型分类 MySQL中,支持各种各样的类型,比如表示数值的整型浮点型,文本、二进制类型、…

RK3568镜像的拆包和打包

文章目录 前言一、window上分包和打包分包打包二、Linux上分包和打包分包打包总结前言 本文记录在win10上利用瑞芯微提供的工具进行分包和打包,同样也有Linux教程 提示:以下是本篇文章正文内容,下面案例可供参考 一、window上分包和打包 分包 window下一般直接利用工具即…

[oeasy]python0094_视频游戏_双人网球_pong_atari_mos_6502_雅达利_米洛华

编码进化 回忆上次内容 上次 我们回顾了 微软之前的 比尔盖茨和保罗艾伦 mits 迎来的 是帮手还是隐患? intel-8080 遇到了 mos-6502 底层硬件 驱动 游戏行业进化 不光是扑克牌和柏青哥了出现了双人网球 不过 目前的游戏 PDP-1 上的《太空大战》Donner Model 30 上…

信号类型(雷达)——脉冲雷达(三)

系列文章目录 《信号类型(雷达通信)》 《信号类型(雷达)——雷达波形认识(一)》 《信号类型(雷达)——连续波雷达(二)》 文章目录 前言 一、相参雷达 1…

从中国文化看面试挑人标准

文章目录标准一、面相1. 1 四白眼1.2 浓眉二、讲话2.1 言多与气虚总结本文结合中国面相,是个概率性问题,对于个体无效。 标准 正直,三观正,沟通好,技术。从概率上讲: 正直且三观正的人----有恒心&#x…

Android OTA 相关工具(四) 查看 payload 文件信息

文章目录1. payload_info.py 的使用1. 环境2. 帮助信息2. 查看 payload 文件信息1. 不带选项查看2. 使用 stats 选项查看3. 使用 signagures 选项4. 使用 list_ops 选项查看3. 其它一直以来,很多人都表达过很想去研究一下 Android OTA 的 payload 文件,看…

Guna Charts WinForm 1.0.8 Crack

Guna Charts 16 图表 在 16 种不同的图表类型中可视化您的数据。 Guna Charts 反应灵敏 轻松响应屏幕尺寸的变化。 Guna Charts 实时图表 创建实时数据仪表板现在非常容易。 Guna Charts 混合图表类型 混合多种图表类型,例如条形图和折线图/面积图。 Guna Charts…

26 openEuler管理网络-使用ip命令配置网络

文章目录26 openEuler管理网络-使用ip命令配置网络26.1 配置IP地址26.1.1 配置静态地址26.1.2 配置多个地址26.2 配置静态路由26 openEuler管理网络-使用ip命令配置网络 说明: 使用ip命令配置的网络配置可以立即生效但系统重启后配置会丢失。 26.1 配置IP地址 使用…

基于stm32电梯管理系统设计

基于stm32电梯管理系统设计这里记录一下以前自己做的嵌入式课程设计,报告中的图片和文字太多了,全部一个一个把搬过来太麻烦了,需要完整文本和代码自行q我963160156,也可在微信公众号 *高级嵌入式软件* 里回复 *电梯* 查看完整版文章摘要关键…

Redis 之企业级解决方案

文章目录一、缓存预热二、缓存雪崩三、缓存击穿四、缓存穿透五、性能指标监控5.1 监控指标5.2 监控方式🍌benchmark🍌monitor🍌slowlog提示:以下是本篇文章正文内容,Redis系列学习将会持续更新 一、缓存预热 1.1 现象…

ctf pwn基础-4

今天是学pwn的第四天,去接触了pwn的整数溢出。 目录 基础 实例讲解 实例讲解2 基础 关于整数溢出,这里以int为例,因为我php之前搞的比较多,以为这个int也是想php一样是64,最大值是9开头的那个,闹了不少笑…

QML Animation动画详解

1.Animation简介 Animation类型提供了四个属性: alwaysRunToEnd:该属性接收布尔类型的参数。该属性保存动画是否运行到完成才停止。当loops属性被设置时,这个属性是最有用的,因为动画将正常播放结束,但不会重新启动。…

算法进阶-动态规划

经典例题 大家肯定想用递归做 思路大概就是这样 递归到最后一行就是对应的D(i,j) 然后往上推 但是这样会超时,因为存在大量的重复计算 比如调用第一行MasSum(7)需要调用MaxSum(3)和MaxSum(8) 但是调用第二行MaxSum(3)还要调用3行的MaxSum(8)和3行的MaxSum(1) 第二行…

人工智能-机器视觉篇搞定(笔记)

考书目《人工智能之机器视觉》–程晨 1.从计算机读取一张图片显示 ##获取图片 import cv2 imcv2.imread("im.jpg") cv2.imshow("my",im) cv2.waitKey() cv2.destroyAllWindows()2.显示视频帧 import cv2 #cap cv2.VideoCapture("video.mp4")获…

java面试题-JVM类加载机制

类加载的生命周期?1. 加载阶段(Loading)在Java程序中,当需要使用某个类时,JVM会使用类加载器来查找并加载该类文件。类加载器会首先从文件系统或网络中查找相应的 .class 文件,读取类的二进制数据&#xff…

链表(一):移除链表元素、设计链表等力扣经典链表题目

203.移除链表元素相关题目链接:力扣 - 移除链表元素题目重现给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val val 的节点,并返回 新的头节点 。思路链表的删除操作如上图所示,我们需要先找到要删除的…