【Java 基础篇】Java 中的 `wait` 与 `notify` 方法详解

news2024/9/28 15:25:45

在这里插入图片描述

在 Java 中,waitnotify 方法是用于线程之间通信的重要工具。它们被用于实现线程的等待与唤醒,以及线程之间的协作。本节将深入介绍这两个方法的使用方式、作用以及一些注意事项。

wait 方法

wait 方法是 java.lang.Object 类的一个实例方法,它用于使当前线程进入等待状态,直到其他线程调用相同对象上的 notifynotifyAll 方法来唤醒它。wait 方法通常与 synchronized 关键字一起使用,以确保线程在等待时不会发生竞态条件。

wait 方法的语法

public final void wait() throws InterruptedException
  • wait 方法没有参数,它将当前线程置于等待状态,直到其他线程调用相同对象上的 notifynotifyAll 方法。

  • InterruptedException 异常表示如果线程在等待过程中被中断,会抛出该异常。

wait 方法的示例

以下是一个简单的示例,演示如何使用 wait 方法等待其他线程的通知:

public class WaitNotifyExample {
    public static void main(String[] args) {
        final Object lock = new Object();

        Thread waiterThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Waiter: Waiting for notification...");
                    lock.wait(); // 进入等待状态
                    System.out.println("Waiter: Got notified!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread notifierThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(2000); // 模拟一些操作
                    System.out.println("Notifier: Notifying waiter...");
                    lock.notify(); // 唤醒等待的线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        waiterThread.start();
        notifierThread.start();
    }
}

在这个示例中,waiterThread 在锁定 lock 对象后调用 lock.wait() 进入等待状态,等待 notifierThread 唤醒它。

notify 方法与 notifyAll 方法

notify 方法和 notifyAll 方法都用于唤醒等待在同一个对象上的线程。主要区别在于:

  • notify 方法只会唤醒一个等待线程(无法确定是哪一个),通常用于特定条件下只需唤醒一个线程的情况。

  • notifyAll 方法会唤醒所有等待线程,通常用于多个线程都需要同时被唤醒的情况。

notify 方法的语法

public final void notify()
  • notify 方法唤醒在相同对象上等待的一个线程。

notifyAll 方法的语法

public final void notifyAll()
  • notifyAll 方法唤醒在相同对象上等待的所有线程。

notifynotifyAll 方法的示例

以下示例演示了如何使用 notify 方法唤醒等待线程:

public class NotifyExample {
    public static void main(String[] args) {
        final Object lock = new Object();

        Thread waiterThread1 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Waiter 1: Waiting for notification...");
                    lock.wait();
                    System.out.println("Waiter 1: Got notified!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread waiterThread2 = new Thread(() -> {
            synchronized (lock) {
                try {
                    System.out.println("Waiter 2: Waiting for notification...");
                    lock.wait();
                    System.out.println("Waiter 2: Got notified!");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread notifierThread = new Thread(() -> {
            synchronized (lock) {
                try {
                    Thread.sleep(2000);
                    System.out.println("Notifier: Notifying waiters...");
                    lock.notify(); // 唤醒等待的线程
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        waiterThread1.start();
        waiterThread2.start();
        notifierThread.start();
    }
}

在这个示例中,notifierThread 在锁定 lock 对象后调用 lock.notify() 唤醒一个等待线程,可以是 waiterThread1waiterThread2 中的任何一个。

注意事项

在使用 waitnotifynotifyAll 方法时,需要注意以下事项:

  1. 这些方法必须在 synchronized 块内调用,以确保线程安全。

  2. 线程在调用 wait 方法时会释放锁,使得其他线程可以获得锁并执行。当线程被唤醒时,它会重新尝试获得锁。

  3. 使用 wait 方法时,通常需要将它包装在一个循环中,以防止虚假唤醒(即在没有被通知的情况下线程被唤醒)。

  4. notify 方法和 notifyAll 方法不会释放锁,它们只是唤醒等待线程,等待线程被唤醒后需要重新竞争锁。

  5. notify 方法通常用于只唤醒一个线程的情况,而 notifyAll 方法用于唤醒所有等待线程的情况。

  6. 在多线程编程中,要小心死锁和竞态条件等问题,确保线程通信的安全性和正确性。

总结

希望本文能够帮助您更好地理解 waitnotify 方法在 Java 多线程编程中的作用和用法。通过合理地使用这些方法,可以实现线程之间的协作与通信,编写出更可靠的多线程程序。

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

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

相关文章

知识图谱(4)图算法

基于图有很多任务,比如: 节点分类:预测哪些网站是诈骗网站;关系预测:判断图中两个节点的关系;图分类:分子性质预测;聚类:社交网络分析,将相似用户聚类在一起…

如何选择合适的官文转录供应商

为什么质量不应该是唯一的考虑因素 官文记录必须准确无误——很多重要的程序(包括法庭案件审判、严重欺诈调查和尸检调查)成功得出结论,可能都依赖于记录的准确性。但是,在选择转录供应商时,还必须考虑更多因素。 官文…

2023Q2全球可穿戴腕带出货量达 4400 万台

全球可穿戴设备市场在2023年第二季度继续保持增长态势,总出货量达到了4400万台,同比增长了6%。这一增长得益于消费者对于可穿戴设备的需求不断增加,以及不同细分市场的需求反弹。 根据市场研究机构 Canalys 的最新报告,全球可穿戴…

阿里测开面试大全(一)附答案完整版

万字长文,建议收藏 1 什么是POM,为什么要使用它? POM是Page Object Model的简称,它是一种设计思想,而不是框架。大概的意思是,把一个一个页面,当做一个对象,页面的元素和元素之间操…

VM虚拟机CentOS7.9x64 LVM硬盘扩容

软件版本:VMWare Workstation14 虚拟机CentOS 7.9X64位 GParted 0.33.0 一、虚拟机安装gparted软件 sudo yum install epel-release sudo yum install gparted sudo yum install yum-utils git gnome-common gcc-c sudo yum-builddep gparted 二、关闭虚拟机&a…

【Java 基础篇】Java Condition 接口详解

Java 提供了一种更灵活和高级的线程协作机制,通过 Condition 接口的使用,你可以更精细地控制线程的等待和唤醒,实现更复杂的线程同步和通信。本文将详细介绍 Java 的 Condition 接口,包括它的基本概念、常见用法以及注意事项。 什…

TS编译器选项​compilerOptions指定编译后文件所在目录

compilerOptions是TS的编译器选项,主要在tsconfig.json文件中用于对ts编译为js文件时进行配置 "compilerOptions" : { 配置项 } 在tsconfig.json中编写如下代码: {// compilerOptions 编译器选项"compilerOptions": {// outDir 用于…

buuctf web [极客大挑战 2019]Upload

上传头像&#xff0c;上传一下&#xff0c;看看能不能成功 抓包&#xff0c;抓取上传时的数据,看看限制条件 改两个地方&#xff0c;符合上传图片的要求&#xff0c;上传试试 一句话木马的<?被扳了 改一下木马的格式 <script language"php">eval($_POST[cm…

[NOIP2016 提高组] 蚯蚓

题目链接 题目很长&#xff0c;题意如下&#xff1a;一开始有n个值&#xff0c;&#xff0c;有m次操作&#xff0c;每次操作选择一个最大的值x&#xff0c;将它分解成两个数&#xff0c;分别为&#xff0c;以及&#xff0c;然后&#xff0c;经过这个操作之后&#xff0c;对除了…

什么是 AirServer?Mac专用投屏工具AirServer 7 .27 for Mac中文破解版百度网盘下载

AirServer 7 .27 for Mac中文免费激活版是一款Mac专用投屏工具&#xff0c;能够通过本地网络将音频、照片、视频以及支持AirPlay功能的第三方App&#xff0c;从 iOS 设备无线传送到 Mac 电脑的屏幕上&#xff0c;把Mac变成一个AirPlay终端的实用工具。 目前最新的AirServer 7.2…

Python常用库(六):科学计算库-Numpy[上篇]:创建、访问、赋值

1.Numpy 1.1 介绍 NumPy是Python中非常流行且重要的科学计算库&#xff0c;提供了一个强大的多维数组对象(ndarray)和许多数学操作&#xff0c;包括矩阵运算、线性代数、微积分等等。 numpy是Python中一个非常有用的工具&#xff0c;特别是在需要进行数值计算、线性代数计算、…

基于nRF7002-DK的NFC功能切换系统(nRF Connect SDK+NFC)

目录 项目介绍硬件介绍项目设计开发环境及工程目录总体流程图硬件初始化NFC功能实现文本记录安卓应用打开按键切换功能 功能展示项目总结 &#x1f449; 【Funpack2-6】基于nRF7002-DK的NFC功能切换系统 &#x1f449; Github: EmbeddedCamerata/nRF7002-DK-nfc-function-switc…

智慧养殖:浅谈视频监控与AI智能识别技术助力奶牛高效、智慧养殖

一、方案背景 随着科技的飞速发展&#xff0c;智能化养殖逐渐成为现代畜牧业的发展趋势。人工智能技术、物联网、视频技术、云计算、大数据等新兴技术&#xff0c;正在为奶牛养殖业带来全新的变革。越来越多的牧场、养殖场开始运用新技术来进行智能监管、提高生产效率、降低生…

就只说 3 个 Java 面试题

在面试时&#xff0c;即使是经验丰富的开发人员&#xff0c;也可能会发现这是一些很棘手的问题&#xff1a; 1、Java中“transient”关键字的用途是什么&#xff1f;如何才能实现这一目标&#xff1f; 在 Java 中&#xff0c;“transient”关键字用于指示类的特定字段不应包含…

蒙特卡洛方法的数学基础-1

蒙特卡洛方法的数学基础-1 概率论 Bayes 公式 常用分布 Binominal Distribution Poisson Distribution Gaussian Distribution Exponential Distribution Uniform Distribution 大数定理 均匀概率分布随机地取N个数xi &#xff0c;函数值之和的算术平均收敛于函数的期望值 …

Cesium 空间量算——生成点位坐标

文章目录 需求分析1. 点击坐标点实现2. 输入坐标实现 需求 用 Cesium 生成点位坐标&#xff0c;并明显标识 分析 以下是我的两种实现方式 第一种是坐标点击实现 第二种是输入坐标实现 1. 点击坐标点实现 //点位坐标getLocation() {this.hoverIndex 0;let that this;this.view…

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

八一书《乡村振兴战略下传统村落文化旅游设计》许少辉瑞博士生辉少许——2023学生开学季许多少年辉光三农

10万单词例句表单词句子ACCESS\EXCEL数据库

原本我以为《3万5千英语句子英语例句大全ACCESS数据库》例句已经够多了&#xff0c;没想到今天遇到一个10万条英语单词例句的数据&#xff0c;非常适合与单词词典进行关联学习&#xff0c;例句多了单词的用法以及句子的掌握都更有效率。 截图下方有显示“共有记录数”&#xff…

Cesium 空间量算——面积量算

面积量算 需求分析 需求 对页面上所选内容进行面积计算 分析 其实&#xff0c;计算面积其实就是把一个面&#xff0c;拆分成一个一个的三角曲面计算然后相加得到&#xff0c;下面是计算的面积的代码 /** * description : 面积量算* author : Hukang* date : 2023-09-20 13:1…

Date类的学习笔记-超级详细

Date 的定义, 在开始研究这个之前我们首先要能够明白一点&#xff0c;这个 Date 其实本质上是一个对象&#xff0c;我们通过这个对象可以去构建变量&#xff0c;知道这个之后就可以开展后续的研究了 JDK 通用 Date 类的构造方法 测试 获取当前的时间 // 构造这个日期对象Date…