【Java多线程编程】wait与notify方法详解

文章详细介绍了Java多线程中wait、notify和notifyAll方法的使用,这些方法常与synchronized配合解决线程间资源竞争问题。wait使线程进入等待状态并释放锁,notify唤醒一个等待的线程,notifyAll唤醒所有等待的线程。文章通过ATM机取款的例子解释了这些方法的用途和区别,并强调它们必须在同步块中使用。另外,对比了wait与sleep方法的不同,wait用于线程间的通信,而sleep只是让线程暂停执行一段时间。
摘要由CSDN通过智能技术生成

 前言

我们知道,线程的调度是无序的,但有些情况要求线程的执行是有序的。因此,我们可以使用 wait() 方法来使线程执行有序。

本期讲解 Java 多线程中 synchronized 锁配套使用的 wait 方法、notify方法和notifyAll方法,以及 wait 方法与 sleep 方法之间的区别、为什么要使用 wait 和 notify 方法。

目录

为什么要使用wait()方法和notify()方法?

1. wait()方法

2. notify()方法

3. wait()和notify()方法的使用

4. notifyAll()方法

5. wait()和sleep()的区别

为什么要使用wait()方法和notify()方法?

当我们的 Java 代码使用 synchronized 进行加锁时,会出现线程之间抢占资源的情况。这样就会导致某一个线程不符合条件却反复抢到资源,其他线程参与不了资源。因此得使用 wait() 方法与 notify() 方法来解决该问题。

通过现实生活中的经历举一例子:

把三个线程比做人,把一台 ATM 机比作锁(synchronized)。当这三个线程去取钱时,线程1优先进入了 ATM 机里面取钱。

当 ATM 里面没有钱时,线程1就出了 ATM 机。但由于线程离开了 ATM 机后,会一直与线程2和线程3抢占 ATM 机,因此会造成一个极端的后果,就是线程1一直进入 ATM 机然后出 ATM 机,并且一直循环下去。

以上例子,线程1发现 ATM 没钱可取,却还是反复进出 ATM 这样这样其他线程就无法尝试取钱,对应的就是多线程中的多个线程竞争锁(synchroized)的情况,如何解决以上问题。

使用 wait 方法和 notify 方法。当 ATM(synchronized) 内使用了 wait 方法,线程1取不了钱就会取消锁状态并且处于等待状态,当其他线程进入 ATM 机并且取到了钱这时候就可以使用 notify 方法唤醒 线程1的等待状态,那么线程1又可以进行取钱操作,也就是进行锁的竞争。

在使用 wait 方法后,线程1发现 ATM 里面没有钱可取,就会通过 wait 方法来释放锁并且进行阻塞等待(也就是暂时不参与 CPU 的调度、锁的竞争),这个时候线程2和线程3就能很好的参与取钱这个操作了。

当其他线程 使用 notify 方法时,发现 ATM 里面又有钱可取了。因此就会唤醒线程1的阻塞等待,这时线程1又可以参与 ATM(锁) 的竞争。直到,所有的线程都取到钱为止。


那么使得上述三个线程能供协调的完成取钱这个工作,会用到三个方法:

  • wait() 方法/带参数的wait()方法 - 让当前线程进入等待阻塞状态
  • notify() 方法 / notifyAll() 方法 - 唤醒当前对象上等待的线程

注意:wait,notify、notifyAll都是 Object 类中的方法。


1. wait()方法

wait 方法使用后:会把当前的执行的线程进行等待阻塞,然后释放当前线程的锁状态,当满足了一定条件后就被唤醒重新尝试获取这个锁

wait 结束条件的为:

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一只爱打拳的程序猿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值