当前位置: 首页 > news >正文

【Java】线程暂停比拼:wait() 和 sleep()的较量

欢迎浏览高耳机的博客

希望我们彼此都有更好的收获

感谢三连支持!

在Java多线程编程中,合理地控制线程的执行是至关重要的。wait()sleep()是两个常用的方法,它们都可以用来暂停线程的执行,但它们之间存在着显著的差异。本文将详细探讨这两个方法的区别,并提供一个实际的编程示例来展示如何使用它们来控制线程的执行顺序。

               当你被罚站时,需要等待解除罚站的指令才能离开;

               而当你睡觉时,到了一定时间自然就会醒来;

wait()sleep()概述

wait()

    定义wait()Object类的一个方法,它使得调用它的线程释放对象的锁,并进入对象的等待池(wait set)。

    用途:主要用于线程间的协作,特别是当一个线程需要等待另一个线程完成某些操作时。

    锁状态:调用wait()的线程必须拥有对象的锁,并且在调用后会释放这个锁。

sleep()

    定义sleep()Thread类的一个静态方法,它使得调用它的线程暂停执行指定的时间。

    用途:通常用于控制线程的执行时间,或者在不释放锁的情况下让其他线程有机会执行。

    锁状态:调用sleep()的线程不会释放任何锁。

wait()必须在同步方法或块中调用。

sleep()可以在任何地方调用。

区别详解

锁状态和对象监视器

    wait()需要在同步方法或块中调用,因为它依赖于对象的锁。调用后,线程会释放锁并进入等待状态。

    sleep()可以在任何地方调用,不需要在同步方法或块中,且不会释放任何锁。

响应中断

           在wait()sleep()期间,如果线程被中断,都会抛出InterruptedException异常。

用途

    wait()通常用于线程间的协作,如生产者-消费者问题。

    sleep()通常用于控制线程的执行时间,或者在不释放锁的情况下让其他线程有机会执行。

返回到执行状态

    wait()在被唤醒后,需要重新获得对象的锁才能继续执行。

    sleep()在睡眠时间结束后自动继续执行,不需要重新获得锁。

实际编程示例

以下是一个使用wait()sleep()来控制线程执行顺序的示例:

    有三个线程,线程名称分别为:a,b,c。 每个线程打印自己的名称。需要让他们同时启动,并按 c,b,a的顺序打印

使用 wait() 实现: 

package Thread;public class Demo11 {private static Object locker = new Object();private static int state = 1;public static void main(String[] args) throws InterruptedException {//通过state这个变量作为判断条件,不满足该条件的线程进入等待,满足条件的线程则先打印,//然后改变条件,通过notify唤醒其他线程,继续判断,打印;Thread thread1 = new Thread(() -> {synchronized (locker) {while(state != 1) {try {locker.wait();}catch (InterruptedException e) {e.printStackTrace();}}System.out.println("C");state = 2;locker.notify();}});Thread thread2 = new Thread(() -> {synchronized (locker) {while(state != 2) {try {locker.wait();}catch (InterruptedException e) {e.printStackTrace();}}System.out.println("B");state = 3;locker.notify();}});Thread thread3 = new Thread(() -> {synchronized (locker) {while(state != 3) {try {locker.wait();}catch (InterruptedException e) {e.printStackTrace();}}System.out.println("A");state = 1;locker.notify();}});thread1.start();thread2.start();thread3.start();thread1.join();thread2.join();thread3.join();}
}

在这个示例中,我们使用了一个共享对象locker作为锁,并通过state变量来控制线程的执行顺序。每个线程在执行前都会检查state变量,如果不符合条件,就会调用wait()方法等待。当一个线程执行完毕后,它会更新state变量并调用notify()方法来唤醒其他等待的线程。

使用 sleep() 实现

package Thread;public class Demo13 {//sleep版
//    有三个线程,线程名称分别为:a,b,c。
//    每个线程打印自己的名称。
//    需要让他们同时启动,并按 c,b,a的顺序打印public static void main(String[] args) throws InterruptedException {Thread thread1 = new Thread(() -> {try {Thread.sleep(200);}catch (InterruptedException e) {e.printStackTrace();}System.out.println("C");});Thread thread2 = new Thread(() -> {try {Thread.sleep(400);}catch (InterruptedException e) {e.printStackTrace();}System.out.println("B");});Thread thread3 = new Thread(() -> {try {Thread.sleep(600);}catch (InterruptedException e) {e.printStackTrace();}System.out.println("A");});thread1.start();thread2.start();thread3.start();thread1.join();thread2.join();thread3.join();}
}

在这个实例中,我们不需要使用synchronized锁来帮助我们控制进程,而是单纯通过每个线程的睡眠时间不同,利用时间差来实现规定的打印顺序;

这种方法虽然更加直观,但请注意,这种方法并不是线程同步的推荐做法,因为它依赖于硬编码的延迟,这可能会导致不可预测的行为,特别是在不同的系统或不同的负载条件下。通常,使用waitnotifyReentrantLockCondition来实现线程间的协调是更可靠和可控的方法。 

结论

理解wait()sleep()的区别对于编写高效的多线程程序至关重要。wait()sleep()都可以用来暂停线程的执行,但它们在锁状态、用途、中断响应等方面有着显著的不同。正确使用这些方法可以帮助你更好地控制线程的执行顺序和协作。

 

相关文章:

【Java】线程暂停比拼:wait() 和 sleep()的较量

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持! 在Java多线程编程中,合理地控制线程的执行是至关重要的。wait()和sleep()是两个常用的方法,它们都可以用来暂停线程的执行,但它们之间存在着显著的差异。本文将详…...

CQRS模型解析

简介 CQRS中文意思为命令于查询职责分离,我们可以将其了解成读写分离的思想。分为两个部分 业务侧和数据侧,业务侧主要执行的就是数据的写操作,而数据侧主要执行的就是数据的读操作。当然两侧的数据库可以是不同的。目前最为常用的CQRS思想方…...

qt-C++笔记之作用等同的宏和关键字

qt-C笔记之作用等同的宏和关键字 code review! Q_SLOT 和 slots: Q_SLOT是slots的替代宏,用于声明槽函数。 Q_SIGNAL 和 signals: Q_SIGNAL类似于signals,用于声明信号。 Q_EMIT 和 emit: Q_EMIT 是 Qt 中用于发射…...

java(3)数组的定义与使用

目录 1.前言 2.正文 2.1数组的概念 2.2数组的创建与初始化 2.2.1数组的创建 2.2.1数组的静态初始化 2.2.2数组的动态初始化 2.3数组是引用类型 2.3.1引用类型与基本类型区别 2.3.2认识NULL 2.4二维数组 2.5数组的基本运用 2.5.1数组的遍历 2.5.2数组转字符串 2.…...

Integer 源码记录

Integer 公共方法结构 注意: 通过构造函数创建一个Integer对象,每次都会返回一个新的对象,如果使用 进行对象的比较,那么结果是false。 public Integer(int value) {this.value value;}与之对应的是,valueOf 方法…...

【RocketMQ】一、基本概念

文章目录 1、举例2、MQ异步通信3、背景4、Rocket MQ 角色概述4.1 主题4.2 队列4.3 消息4.4 生产者4.5 消费者分组4.6 消费者4.7 订阅关系 5、消息传输模型5.1 点对点模型5.2 发布订阅模型 1、举例 以坐火车类比MQ: 安检大厅就像是一个系统的门面,接受来…...

笔记9.18

线程之间的通信是指在多线程程序中,不同线程之间如何交换数据或协调工作。这种通信对于实现复杂的并发程序是至关重要的。以下是几种常见的线程间通信方式: 共享内存: 这是最直接的方式,多个线程通过读写同一块内存区域&#xff0…...

时间序列8个基准Baseline模型及其详细解读

我是从去年11月份开始,选定时间序列预测这个方向,准备在工作之余继续独立进行一些科学研究。选定这个方向是因为我对金融量化一直挺感兴趣,希望能把时间序列中的深度学习算法模型,用到金融数据。现在看来,我太过于理想…...

将相机深度图转接为点云的ROS2功能包

depth_image_proc 是一个 ROS(Robot Operating System)包,它包含了一系列节点,用于处理来自深度相机的图像数据,并将其转换为点云。以下是 depth_image_proc 包中各个节点的作用: convert_metric_node&…...

计算机毕业设计选题推荐-共享图书管理系统-小程序/App

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…...

架构师:在 Spring Cloud 中实现全局异常处理的技术指南

1、简述 在分布式系统中,微服务架构是最流行的设计模式之一。Spring Cloud 提供了各种工具和库来简化微服务的开发和管理。然而,随着服务的增多,处理每个服务中的异常变得尤为复杂。因此,实现统一的全局异常处理成为了关键。本篇博客将介绍如何在 Spring Cloud 微服务架构…...

es由一个集群迁移到另外一个集群es的数据迁移

迁移es的数据 改下index的索引 就可以了。 查询 用curl -u就可以查询了...

java项目之常规应急物资管理系统(源码+文档)

风定落花生,歌声逐流水,大家好我是风歌,混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的常规应急物资管理系统。项目源码以及部署相关请联系风歌,文末附上联系信息。 项目简介: 基于SpringBootVue的…...

text2sql方法:RESDSQL和DAIL-SQL

之前介绍了text2sql的综述,但是对一些方法的描述不够详细,所以将一些感兴趣的方法思路也整理一下。 RESDSQL RESDSQL出自2023年2月的论文《RESDSQL: Decoupling Schema Linking and Skeleton Parsing for Text-to-SQL》(github)。它使用seq2seq PLM(pr…...

Stable Diffusion 优秀博客转载

初版论文地址:https://arxiv.org/pdf/2112.10752 主要流程图: Latent Diffusion Models(LDMs) DDPM是"Denoising Diffusion Probabilistic Models"的缩写, 去噪扩散概率模型 博客: 【论文阅读…...

探索IT行业的无限潜力:技术、发展与职业前景

探索IT行业的无限潜力:技术、发展与职业前景 1. 引言 信息技术(IT)已经彻底改变了我们的生活方式,从智能手机到云计算,IT无处不在。无论是公司管理系统、社交媒体,还是大数据分析平台,IT推动了…...

ESP32配网接入Wifi

1 ESP32的两种模式 AP模式:ESP32可以作为热点,手机和电脑等设备接入使用。 STA模式:ESP32可以作为作为客户端接入其他网络中。 2 流程 step1: ESP32上电后进入STA模式,尝试看能够接入网络 step2: 如何连接成功,则正常运行。如何连接超时,则自动进入AP模式,设置AP热点…...

前端-js例子:收钱转账

支付宝转账 在这里用到周期定时器setInterval(function,time),设置达到目标钱数时停止定时器。 点击转账按钮时,开始函数显示。 同时要确定输入框里输入的是数字。(有一定容错) window.onloadfunction(){var btn document.que…...

2024 BaseCTF repwn 部分wp

You are good at IDA 附件拖入ida。比较简单 UPX mini upx壳,无魔改,直接脱。脱完拖入ida。比较简单 Ez Xor 附件拖入ida 比较简单。脚本 ez_maze 附件拖入ida 一个宽为15的迷宫 BasePlus 附件拖入ida。变表base64再异或0xE 签个到吧 nc连上即得 echo nc…...

每日学习一个数据结构-倒排表

文章目录 示意图倒排表的基本概念倒排表的数据结构示例 倒排表的优点应用场景 倒排表(Inverted Index),也称为反向索引或倒排文件,在信息检索系统中是一种重要的数据结构。它主要用于快速搜索文档中的关键词,并找到包含…...

Python爬虫实战:研究MechanicalSoup库相关技术

一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别

一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...