【六】一文让你迅速掌握wait和notify

在实际的开发中我们有时候希望合理的协调多个线程之间的执行先后顺序,这个时候就要涉及到3个方法了:

  • wait() / wait( long timeout) :让当前线程进入等待状态
  • notify() / notifyAll():唤醒在当前对象上等待的线程
  • 注意:上述三个方法都是 Object 类的方法

1. 注意事项

先看一段代码

public class Demo24 {
    public static void main(String[] args) throws InterruptedException {
        Object object = new Object();
        System.out.println("wait 之前");
        object.wait();
        System.out.println("wait 之后");
    }
}

在这里插入图片描述
通过结果可以看出!此时抛出了一个异常,这是因为这把锁都没获取到,你就尝试解锁,所以wait()必须是写在 synchronized 代码块里面! notify()也是必须写在 synchronized 代码块里面!

wait 主要做3件事:
1.解锁
2.阻塞等待
3.当收到通知的时候,就唤醒,同时尝试重新获取锁~


public class Demo24 {
    public static void main(String[] args) throws InterruptedException {
        Object locker = new Object();
        Thread t1 = new Thread(() -> {
            try {
                System.out.println("wait 开始");
                synchronized (locker) {
                    locker.wait();
                }
                System.out.println("wait 结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t1.start();

        Thread.sleep(1000);

        Thread t2 = new Thread(() -> {
            try {
                synchronized (locker) {
                    System.out.println("notify 开始");
                    locker.notify();
                    System.out.println("notify 结束");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        t2.start();
    }
}

在这里插入图片描述
上述代码的执行流程是,当 t1 先执行,执行到 wait 就阻塞了,然后1s之后,t2 开始执行,执行到了notify 就会通知 t1 线程唤醒!但是此时 notify 是在 synchronized 内部,就需要 t2 释放锁后,t1 才能继续往下走。

在上述代码中,虽然 t1 先执行的,但是我们可以通过 wait notify 控制 让 t2 先执行一些逻辑,在 t2 执行完之后,notify 唤醒 t1,t1 再继续往下执行。

  • wait 也提供了一个带参数的版本,参数指定的是最大等待时间,如果超过这个时间,就会自动唤醒
  • 使用 wait 阻塞等待会让线程进入 WAITING 状态。
  • 唤醒操作,还有个 notifyAll,如果多个线程都调用了 object.wait ,此时 main 方法中调用 object.notify 会随机唤醒上述的一个线程(另外两个仍然是 WAITING 状态);如果是 调用 object.notifyAll,此时会唤醒全部线程,此时多个线程之间就会重新竞争锁!

2. sleep 和 wait 区别 (经典面试题)

首先最大的区别是设计的初心不同~

  • wait 解决的是线程之间的顺序控制
  • sleep 单纯是让当前线程休眠一会

使用上也有区别

  • wait 要搭配 synchronized 使用
  • sleep 不需要

所属的类不同

  • wait 是 Object 所属方法
  • sleep 是 Thread 类的静态方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个想打拳的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值