wait()方法与await()方法的区别

news/2024/11/19 15:23:44/文章来源:https://www.cnblogs.com/luorongxin/p/18554926

wait() 方法与 await() 方法的区别

这两种方法都与线程或异步任务的协调有关,但它们用于不同的场景,并且行为和语法都不相同。


1. wait() 方法

定义与场景

  • 所属java.lang.Object 类。

  • 用途:用于线程间的通信,通常与 notify()notifyAll() 方法一起使用。

  • 场景:在多线程程序中,一个线程等待某些条件满足,而另一个线程通知它继续执行。

关键特点

  • 必须在同步块(synchronized)或同步方法中调用,否则会抛出 IllegalMonitorStateException

  • 调用 wait() 的线程会释放锁并进入 等待状态,直到另一个线程调用 notify()notifyAll() 唤醒它。

  • 属于阻塞操作,调用后线程会停止运行,直到被唤醒。

语法

synchronized (lock) {lock.wait();  // 释放锁并进入等待状态
}

  

示例

class WaitNotifyExample {private static final Object lock = new Object();
​public static void main(String[] args) {Thread t1 = new Thread(() -> {synchronized (lock) {try {System.out.println("Thread 1 is waiting...");lock.wait();System.out.println("Thread 1 is resumed!");} catch (InterruptedException e) {e.printStackTrace();}}});
​Thread t2 = new Thread(() -> {synchronized (lock) {System.out.println("Thread 2 is notifying...");lock.notify();}});
​t1.start();t2.start();}
}

  

输出
Thread 1 is waiting...
Thread 2 is notifying...
Thread 1 is resumed!

2. await() 方法

定义与场景

所属:java.util.concurrent.locks.Condition 接口。用途:用于高级线程协调,通常结合 ReentrantLock 使用。场景:细粒度控制线程的等待和唤醒操作,在并发编程中提供更灵活的机制。关键特点
必须在锁对象(如 ReentrantLock)的条件中使用,不能在普通的同步块中使用。与 wait() 类似,调用线程会释放锁并进入等待状态,直到被其他线程通过 signal() 或 signalAll() 唤醒。提供更好的线程通信控制,可以使用多个条件(Condition),而不像 wait() 只能针对一个对象锁。语法
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
​
lock.lock();
try {condition.await(); // 释放锁并进入等待状态
} finally {lock.unlock();
}示例
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
​
class AwaitSignalExample {private static final ReentrantLock lock = new ReentrantLock();private static final Condition condition = lock.newCondition();
​public static void main(String[] args) {Thread t1 = new Thread(() -> {lock.lock();try {System.out.println("Thread 1 is waiting...");condition.await();System.out.println("Thread 1 is resumed!");} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}});
​Thread t2 = new Thread(() -> {lock.lock();try {System.out.println("Thread 2 is signaling...");condition.signal();} finally {lock.unlock();}});
​t1.start();t2.start();}
}

  

输出

Thread 1 is waiting...
Thread 2 is signaling...
Thread 1 is resumed!

对比总结

特性wait()await()
所属类 java.lang.Object java.util.concurrent.locks.Condition
使用锁类型 Java 内置锁(synchronized 显式锁(ReentrantLock
等待/唤醒方法 wait() / notify() / notifyAll() await() / signal() / signalAll()
是否释放锁 释放锁,等待被通知 释放锁,等待被通知
灵活性 只能使用一个对象锁,功能较为简单 可以为不同条件创建多个 Condition,功能更强大
线程安全控制粒度 粒度较粗 粒度更细
是否支持中断 可以通过 InterruptedException 被中断 同样支持 InterruptedException

选择建议

  • wait()

    • 如果是传统的 synchronized 代码块,使用 wait() 即可。

    • 适合简单的线程间协调。

  • await()

    • 如果需要更复杂的线程控制(如多个条件或高级同步机制),推荐使用 await()ReentrantLock

    • 更适合高并发场景。

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

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

相关文章

不可思议!7、8 年外包进了国企!!

大家好,我是R哥。 今天分享一个非常「难以置信」的辅导案例,一个「双非二本」的兄弟从毕业就开始干外包,一直干了 7、8 年外包,从外包离职后,经过我们几个月的面试辅导,最终去了某国企,还是待遇最好的 10 家国企之一。 这兄弟是 5 月份加入面试辅导的,距离他离职已经个…

制造业怎么用好仓库管理系统?仓库管理系统在制造业中的应用实例

随着科技的发展,制造企业对仓库管理的要求也越来越高。大家都在想,怎么能用智能化、自动化的方法来提高仓库的工作效率,减少库存积压,同时让客户更满意。这可是企业发展的一个很关键的问题。这篇文章会通过几个实际的例子,详细讲讲WMS在制造业里是怎么发挥作用的。目的就是…

如何快速推进项目?这些企业用了哪些项目管理工具?

在当今复杂的商业环境中,项目管理不仅仅是管理任务和时间的工具,它已经成为推动团队协作、提升企业执行力以及实现战略目标的核心环节。随着数字化转型的推进,越来越多的企业和团队开始借助智能化的项目管理软件来优化资源配置、提升工作效率、降低风险,最终实现项目的成功…

单变量微积分学习笔记:函数图像的伸缩变换(15)

平移 x:左加右减y:上加下减伸缩\(af(bx+c)+d\) \(x_2=bx+c\),相当于 \(x\) 轴变为原来的 \(\frac{1}{b}\) 后再向左移动 \(c\) \(x=\frac{x_2-c}{b}\) \(y_2=ay+d\),相当于 \(y\) 轴变为原来的 \(\frac{1}{a}\) 后再向上移动 \(d\) \(y=\frac{y_2-d}{c}\)

设置数据库环境变量 win10

方法 1: 使用系统设置界面打开系统属性:在桌面上,右键点击“此电脑”或“我的电脑”,选择“属性”。 在打开的窗口中,点击“高级系统设置”。打开环境变量设置:在“系统属性”窗口中,点击“高级”选项卡下的“环境变量”按钮。设置环境变量:在“环境变量”窗口中,你会看…

小程序开发遇到的问题

真机调试转发给朋友图片加载会失败的问题 在开发工具中分享页面时,图片正常,体验版或手机真机调试时,图片加载失败。电脑上正常,手机上加载失败。 原因是图片的文稿类型为AV1,很多移动设备可能不支持 AV1 解码。 解决办法: 更换为文稿类型为JPEG的图片,图片格式可以是jpg…

用户登录-路由和权限校验

绿色框框是前端,黄色框框是后端。一开始不存在token,若路由存在白名单中,比如login页面,此时会将app.vue中的替换成 login 组件。因为我们在路由中定义了login组件。👆 login/index 动态路由原理 去看文档当中的相应内容。 路由重定向原理 面包屑导航如果只是简单的页面切…

刀片计算机设计方案:192-6U VPX i7 刀片计算机

一、产品概述 该产品是一款基于第三代Intel i7双核四线程(或四核八线程)的高性能6U VPX刀片式计算机。产品提供了可支持全网状交换的高速数据通道,其中P1,P2各支持4个PCIe x4 Gen3总线接口。该产品具有很强的扩展性,可以很好满足多负载多节点的应用需求。 产品…

python调用C#的dll

1、使用VisualStudio建立C#的dll项目 2、编写C#代码生成dll库 3、安装pythonnet 库用于调用C#的dllpip install pythonnet4、编写python代码import clr # 引入 clr 模块,它是 pythonnet 提供的 import sys# 添加 C# DLL 所在的目录 sys.path.append(rCsharp_dll_test.dll)# …

Java防止反编译的技术方案

背景 由于Java字节码的抽象级别较高,因此它们较容易被反编译。本文介绍了几种常用的方法,用于保护Java字节码不被反编译。 通常,这些方法不能够绝对防止程序被反编译,而是加大反编译的难度而已,因为这些方法都有自己的使用环境和弱点。 不同保护技术比较表 以下几种技术都…

销售的“套路”

很多人一谈到销售,就简单的认为是“卖东西”,这只是对销售很片面的理解,其实人生无处不在销售,销售实际上是一个分析需求、判断需求、解决需求、满足需求的过程。 销售是有规律可循的,就像拨打电话号码,次序是不能错的。 一、调动情绪,就能调动一切 良好的情绪管理(情商…

LeetCode 1290[二进制链表转整数]

LeetCode 1290[二进制链表转整数]题目 链接 LeetCode 1290[二进制链表转整数] 详情实例提示题解 思路 遍历链表,获取链表的值添加到容器内 在容器内遍历值,由高位到地位遍历,为权重,然后算值 代码 /*** Definition for singly-linked list.* struct ListNode {* int va…