首页 > 其他分享 >wait()方法与await()方法的区别

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

时间:2024-11-19 15:07:27浏览次数:1  
标签:ReentrantLock Thread lock await 线程 方法 wait

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

    • 更适合高并发场景。

标签:ReentrantLock,Thread,lock,await,线程,方法,wait
From: https://www.cnblogs.com/luorongxin/p/18554926

相关文章

  • unity 3D音 发布PICO后出现问题的解决方法
    发声物体:将AudioSource设置为2D音然后在发声物体上挂载PXR_Audio_Spatializer_AudioSource  收声物体:除了挂载AudioListener外还需要挂载PXR_Audio_Spaializer_AudioListener 此外,还可以找个合适的位置挂载一个PXR_Au......
  • 将 EX4 TO MQ4 的注意事项和方法
    将`.ex4`文件转换为`.mq4`文件本质上涉及反编译`.ex4`文件,这是一个需要注意的重要问题,1**正确的处理方法**  如果您有修改`.ex4`的需要,可以尝试以下方法:  -**联系开发者**:联系原作者,获取`.mq4`源代码或请求他们进行修改。  -**重新开发**:根据需要功......
  • 调整方法和相关的注册表项,能帮助你加速 MS Edge 的加载:增强 Google Chrome 浏览器在视
    在Windows11系统中,通过调整MicrosoftEdge浏览器的注册表设置,你可以对其性能进行优化,尤其是提高启动速度和加载速度。以下是一些常见的调整方法和相关的注册表项,能帮助你加速MSEdge的加载:1. 禁用硬件加速硬件加速可能会影响性能,尤其是在资源较少的设备上。如果你遇到性......
  • Oracle数据库安全扫描1158/3938端口出现弱SSL加密算法解决方法之一
    问题复述某国企项目现场反应安全扫描出部署某历史项目的Windows服务器上的1158及3938两个端口出现了弱SSL加密算法漏洞,要求整改。经过核实,该Windows服务器上部署了tomcat与Oracle11g数据库,其中1158和3938两个端口均为Oracle数据库所使用。处理思路确认1158和3938作用:如果没......
  • [Java] 浮点数的精度丢失问题与精度控制方法
    1需求描述场景1:两个整型相除,如何保证运算结果为浮点数?如何控制运算结果的精度(小数位数)?场景2:针对一个浮点数,如何控制其精度(小数位数)?2试验场景:两整型数相除,控制运算结果、浮点数的精度Longnumber1=110600L;intnumber2=999;intscale=2;//精度n(保留n位小数)/......
  • VLC多媒体播放器 合并字幕srt文件和mp4文件 方法
    转载自:链接:https://blog.csdn.net/sdkdlwk/article/details/143867825作者:sdkdlwk 步骤:1. 将视频和字幕放到同一个文件夹,并保证二者名字相同。选择菜单"媒体"->"流"或者ctrl+s点"添加"选择视频文件,注意这里不要选择下面的使用字幕文件 点击"串流"2. 一直往下点,直......
  • 完美解决PHP无法上传大文件方法
    前端:vue2,vue3,vue-cli,html5,jquery,webuploader后端:php服务器:linux,centos,Windows,数据库:MySQL,达梦数据库,人大金仓功能:分片,断点续传,加密传输,加密存储昨天晚上一个网友给我发私信聊了一下这个需求,他也是最近在项目上遇到这个需求,但是之前没做过这块,技术积累不够,网上......
  • Rust impl关键字(实现封装、继承和多态等功能)(Rust关联类型、impl关联类型、Rust静态方
    文章目录Rust中的`impl`关键字详解什么是`impl`关键字?`impl`的基本语法示例:为结构体实现方法`impl`与特征(Trait)(为类型实现通用接口)示例:为类型实现特征`impl`与关联类型(关联类型使得在特征中定义的一些类型可以在实现时具体化)示例:使用关联类型`impl`与静态方法(不带self......
  • 大规模向量检索与量化方法
    1.向量检索在向量检索中,KNN(K-NearestNeighbors)和ANN(ApproximateNearestNeighbor)是两种最常见的方法,它们都用于根据特征向量找到数据点之间的相似性,但它们在精确度和效率上有所不同。KNN是一种基本的分类和回归方法,它根据一个样本在特征空间中的K个最近邻样本的类别,来预测该......
  • java 创建线程的三种方法(Thread,Runnable,Callable)ExecutorService
    1.继承Thread类2.实现Runnable接口3.实现Callable接口4.线程池1.继承Thread类packagecom.chen;//创建线程的方式:继承Thread,重写run(),调用start()开启线程//注意,线程开启不一定立即执行,由cpu调度执行publicclassTestThread2extendsThread{@Overridepublicvoid......