
前言
我们知道,线程的调度是无序的,但有些情况要求线程的执行是有序的。因此,我们可以使用 wait() 方法来使线程执行有序。
本期讲解 Java 多线程中 synchronized 锁配套使用的 wait 方法、notify方法和notifyAll方法,以及 wait 方法与 sleep 方法之间的区别、为什么要使用 wait 和 notify 方法。
目录

为什么要使用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 结束条件的为:
文章详细介绍了Java多线程中wait、notify和notifyAll方法的使用,这些方法常与synchronized配合解决线程间资源竞争问题。wait使线程进入等待状态并释放锁,notify唤醒一个等待的线程,notifyAll唤醒所有等待的线程。文章通过ATM机取款的例子解释了这些方法的用途和区别,并强调它们必须在同步块中使用。另外,对比了wait与sleep方法的不同,wait用于线程间的通信,而sleep只是让线程暂停执行一段时间。
最低0.47元/天 解锁文章

197

被折叠的 条评论
为什么被折叠?



