java多线程sleep() 和 wait() 有什么区别?

大家好,我是锋哥。今天分享关于【java多线程sleep() 和 wait() 有什么区别?】面试题。希望对大家有帮助;

java多线程sleep() 和 wait() 有什么区别?

在Java中,sleep()wait() 都是多线程编程中常用的控制线程执行的方法。它们看似有相似之处,但实际上在应用场景和行为机制上有很多不同之处。本文将详细阐述这两者的区别,并帮助大家更好地理解如何在多线程编程中正确使用它们。

1. sleep() 方法

sleep()Thread 类中的一个静态方法,用于让当前线程暂停执行一段时间。调用 sleep() 方法的线程会进入“休眠”状态,暂停执行直到指定的时间过去。sleep() 方法不会释放锁,它只是让线程在指定的时间内停止运行。

语法:
Thread.sleep(long millis) throws InterruptedException
Thread.sleep(long millis, int nanos) throws InterruptedException
  • millis:睡眠的毫秒数
  • nanos:额外的纳秒数(适用于更精确的时间控制)
特点:
  1. 不释放锁:调用 sleep() 后,当前线程依然持有它在执行之前获得的锁,直到 sleep() 方法结束。这意味着如果当前线程持有一个对象的锁,其他线程不能访问该对象的同步方法或同步块。
  2. 不会释放对象的监视器:由于 sleep() 不涉及等待或释放对象监视器,它不会改变线程的同步状态。
  3. 阻塞当前线程sleep() 方法只是简单地让线程进入一个休眠状态,过了指定时间后,线程会自动恢复执行。
示例:
public class SleepExample {
    public static void main(String[] args) throws InterruptedException {
        System.out.println("Thread going to sleep...");
        Thread.sleep(2000); // 让当前线程休眠2秒
        System.out.println("Thread woke up after 2 seconds.");
    }
}

2. wait() 方法

wait()Object 类中的一个实例方法,它是用于线程之间通信的工具。wait() 方法会导致当前线程放弃对象的监视器,并使当前线程进入“等待”状态,直到其他线程通过调用同一对象的 notify()notifyAll() 方法来唤醒它。

语法:
public final void wait() throws InterruptedException
public final void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
  • timeout:最大等待时间,单位是毫秒
  • nanos:额外的纳秒时间,用于更精确的等待控制
特点:
  1. 释放锁:当线程调用 wait() 方法时,它会释放当前对象的锁,并进入该对象的等待池中,直到其他线程调用该对象的 notify() 或 notifyAll() 方法来唤醒它。wait() 方法通常与 synchronized 关键字一起使用,以保证在多个线程之间的安全通信。
  2. 线程通信机制wait() 用于线程之间的协调和通信。它使线程等待某个条件的发生,然后才能继续执行。
  3. 阻塞线程:调用 wait() 后,线程会进入阻塞状态,并且在被其他线程通过 notify() 或 notifyAll() 唤醒之前无法继续执行。
示例:
class Counter {
    private int count = 0;
    
    public synchronized void increment() throws InterruptedException {
        while (count == 5) {
            wait();  // 当count为5时,等待其他线程通知
        }
        count++;
        System.out.println("Count incremented to: " + count);
        notify();  // 通知其他等待的线程
    }
    
    public synchronized void decrement() throws InterruptedException {
        while (count == 0) {
            wait();  // 当count为0时,等待其他线程通知
        }
        count--;
        System.out.println("Count decremented to: " + count);
        notify();  // 通知其他等待的线程
    }
}

public class WaitExample {
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        
        // Increment thread
        Thread incrementThread = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    counter.increment();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        
        // Decrement thread
        Thread decrementThread = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    counter.decrement();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        
        incrementThread.start();
        decrementThread.start();
        
        incrementThread.join();
        decrementThread.join();
    }
}

3. sleep() 和 wait() 的主要区别

特性sleep()wait()
所属类Thread 类中的静态方法Object 类中的实例方法
释放锁不释放锁会释放锁
阻塞线程的方式阻塞当前线程指定的时间阻塞当前线程直到被其他线程通过 notify() 或 notifyAll() 唤醒
适用场景用于让线程暂停执行,不关心线程间的交互用于线程间的协作,适合线程之间的等待与通知机制
异常处理会抛出 InterruptedException 异常会抛出 InterruptedException 异常
常与 synchronized不需要与 synchronized 一起使用通常与 synchronized 一起使用,以保证线程安全

4. 使用场景总结

  • sleep():通常用于让当前线程暂停执行一段时间,不涉及线程间的协调或通信。适用于定时任务、暂停、等待特定时间后继续执行等场景。

  • wait():通常用于线程间的协调与通信,适用于生产者-消费者模型、线程池中的任务等待等需要同步和通信的场景。调用 wait() 时必须在 synchronized 块中使用,以确保线程安全。

5. 小结

尽管 sleep()wait() 都会导致线程进入阻塞状态,但它们的应用场景和工作机制有所不同。sleep() 用于简单地让线程暂停一段时间,而 wait() 则用于线程间的协作,通常在多线程共享资源时配合 synchronized 使用。在实际开发中,我们需要根据具体的需求来选择合适的机制,以保证程序的正确性和高效性。

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

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

相关文章

从无音响Windows 端到 有音响macOS 端实时音频传输播放

以下是从 Windows 端到 macOS 端传输音频的优化方案&#xff0c;基于上述链接中的思路进行调整&#xff1a; Windows 端操作 安装必要软件 安装 Python&#xff08;确保版本兼容且已正确配置环境变量&#xff09;。安装 PyAudio 库&#xff0c;可通过 pip install pyaudio 命令…

测度论原创(三)

Morden Prob 文章目录 Morden ProbWeek3多维扩展和随机向量定理3.1推论&#xff1a;random variable的变换定理3.2 连续函数的可测性定理3.3 可测函数的线性组合关于拓展实数集的延伸定理3.4 可测函数的极限依旧为可测性随机变量的概率律&#xff08;Law of X X X&#xff09;…

【C++】C++移动语义、左值右值、左值引用右值引用、移动构造函数、std::move、移动赋值操作符

二十五、C移动语义、左值和右值、左值引用右值引用、移动构造函数、std::move、移动赋值操作符 本部分讨论一些更高级的C特性&#xff1a;C移动语义。但是讲移动语义之前我们得先了解什么左值右值、左值引用和右值引用。 1、C的左值和右值、左值引用和右值引用左值是有地址的…

uniapp实现H5和微信小程序获取当前位置(腾讯地图)

之前的一个老项目&#xff0c;使用 uniapp 的 uni.getLocation 发现H5端定位不准确&#xff0c;比如余杭区会定位到临平区&#xff0c;根据官方文档初步判断是项目的uniapp的版本太低。 我选择的方式不是区更新uniapp的版本&#xff0c;是直接使用高德地图的api获取定位。 1.首…

Pycharm,2024最新版Pycharm下载安装配置教程!

目录 1、Pycharm 简介2、Pycharm下载3、环境变量的配置4、Pycharm的使用 1、Pycharm 简介 Pycharm资料领取不收米 PyCharm是一种Python IDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Py…

(十三)JavaWeb后端开发——MySQL2

目录 1.DQL数据查询语言 1.1基本查询 1.2条件查询 where关键字 1.3分组查询 1.4排序查询 1.5分页查询 2.多表设计 3.多表查询——联查 4.多表查询——子查询​ 5.MySQL 事务 6.事务管理&#xff08;事务进阶&#xff09; 7.MySQL 索引 1.DQL数据查询语言 分为五大…

C++虚继承演示

在继承中如果出现&#xff1a; 这种情况&#xff0c;B和C都继承了A&#xff0c;D继承了B、C 在D中访问A的成员会出现&#xff1a; 这样的警告 是因为在继承时A出现两条分支&#xff1a;ABD、ACD 编译器不知道访问的A中的元素是经过B继承还是C继承 所以B、C在继承A时要用到…

【论文速看】DL最新进展20241109-图像超分、物理信息神经网络、扩散模型

目录 【图像超分】【物理信息神经网络】【扩散模型】 【图像超分】 [2024 红外图像超分] Infrared Image Super-Resolution via Lightweight Information Split Network 论文链接&#xff1a;https://arxiv.org/pdf/2405.10561v2 代码链接&#xff1a;无 单图像超分辨率&…

革命性AI搜索引擎!ChatGPT最新功能发布,无广告更智能!

文章目录 零、前言一、ChatGPT最新AI搜索引擎功能操作指导实战1:搜索新闻实战2:搜索天气实战3:搜索体育消息 二、感受 零、前言 大人&#xff0c;时代变了。 最强 AI 助力下的无广告搜索引擎终于问世。我们期待已久的这一刻终于到来了&#xff0c;从今天起&#xff0c;ChatGPT…

qt QLocale详解

1、概述 QLocale是Qt框架中的一个类&#xff0c;用于处理与本地化相关的操作。它能够方便地实现日期、时间、数字和货币的格式化和解析&#xff0c;支持不同的语言、区域设置和字符集。QLocale提供了一种跨平台的方式来获取当前系统的语言设置&#xff0c;并返回该语言的本地化…

Linux基础4-进程4(环境变量,命令行参数详解)

上篇文章:Linux基础4-进程3(进程优先级&#xff0c;竞争&#xff0c;独立&#xff0c;并行&#xff0c;并发&#xff0c;进程切换)-CSDN博客 本章重点: Linux中环境变量的理解和使用 目录 一. 环境变量概念和查看环境变量 1.1 环境变量概念 1.2 查看环境变量 二. 获取环境变…

Java学习路线:Maven(一)认识Maven

目录 认识Maven 新建Maven文件 导入依赖 认识Maven Maven是一个Java的项目管理工具&#xff0c;通过Maven&#xff0c;我们可以实现&#xff1a; 项目自动构建&#xff0c;包括代码的编译、测试、打包、安装等依赖管理&#xff0c;快速完成依赖的导入 在学习Maven之前&…

Node.js——fs模块-文件删除

1、在Node.js中&#xff0c;我们可以使用unlink或unlinkSync来删除文件。 2、语法&#xff1a; fs.unlink(path,callback) fs.unlinkSync(path) 参数说明&#xff1a; path 文件路径 callback 操作后的回调函数 本文的分享到此结束&#xff0c;欢迎大家评论区一同讨论学…

PG逻辑复制的REPLICA IDENTITY几种设置

前两天同事问了一个PG的错误&#xff0c;创建一张普通表&#xff0c;insert插入正常&#xff0c;但是执行update和delete时&#xff0c;提示这个错误&#xff0c; 代码语言&#xff1a;javascript 复制 SQL 错误 [55000]: ERROR: cannot delete from table "temp_tb&qu…

【人工智能】利用大语言模型(LLM)实现机器学习模型选择与实验的自动化

文章目录 引言环境准备数据集说明 项目结构主要文件说明 导入必要的软件包软件包功能简述 辅助函数定义加载配置文件加载数据集预处理数据集函数功能详解 集成LLM进行模型选择调用LLM的函数定义函数功能详解 清理和验证LLM的输出清理超参数建议提取模型名称验证超参数修正超参数…

机器学习在时间序列预测中的应用与实现——以电力负荷预测为例(附代码)

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 随着数据采集技术的发展&#xff0c;时间序列数据在各个领域中的应用越来越广泛。时间序列预测旨在基于过去的时间数据来…

Python学习------第四天

Python的判断语句 一、布尔类型和比较运算符 二、 if语句的基本格式 if语句注意空格缩进&#xff01;&#xff01;&#xff01; if else python判断语句的嵌套用法&#xff1a;

Vue3版本的uniapp项目运行至鸿蒙系统

新建Vue3版本的uniapp项目 注意&#xff0c;先将HbuilderX升级至最新版本&#xff0c;这样才支持鸿蒙系统的调试与运行&#xff1b; 按照如下图片点击&#xff0c;快速升级皆可。 通过HbuilderX创建 官方文档指导链接 点击HbuilderX中左上角文件->新建->项目 创建vue3…

让Apache正确处理不同编码的文件避免中文乱码

安装了apache2.4.39以后&#xff0c;默认编码是UTF-8&#xff0c;不管你文件是什么编码&#xff0c;统统按这个来解析&#xff0c;因此 GB2312编码文件内的中文将显示为乱码。 <!doctype html> <html> <head><meta http-equiv"Content-Type" c…

LabVIEW实验室液压制动系统

压制动系统是许多实验设备的重要安全组件&#xff0c;尤其在高负荷、高速实验环境下&#xff0c;制动系统的性能对设备和操作人员的安全至关重要。传统的实验室液压制动系统监测方法存在数据采集实时性差、精度低、故障预警不及时等问题。为了提高实验安全性和设备运行的稳定性…