面试常常说使用wait、notify、notifyAll必须在同步代码块里也就是和synchronized一起用,为啥呢?
在Java中,synchronized关键字用于实现线程的互斥访问,即同一时刻只能有一个线程执行被synchronized关键字包裹的代码块或方法。这样可以确保在共享资源上的操作是线程安全的。
wait()方法用于使当前线程进入等待状态,直到其他线程调用相同对象的notify()或notifyAll()方法来唤醒它。当一个线程调用wait()方法时,它会释放当前持有的锁,允许其他线程进入临界区并执行相关操作。
notify()方法用于唤醒一个正在等待的线程。如果有多个线程等待,只能唤醒其中一个线程,具体唤醒哪个线程是不确定的。notifyAll()方法则会唤醒所有等待的线程,让它们重新竞争锁。
现在我们来看看为什么wait()、notify()和notifyAll()需要与synchronized一起使用:
1.线程安全
wait()、notify()和notifyAll()方法必须在同步块或同步方法中调用,以确保在调用这些方法时,当前线程已经获取了对象的监视器锁(即通过synchronized获取锁),这样才能对锁进行释放或唤醒等操作。
2.监视器锁的释放和恢复
当一个线程调用wait()方法时,它会释放当前持有的监视器锁,让其他线程能够获得该锁并执行相关操作。当调用notify()或notifyAll()方法时,被唤醒的线程会重新竞争获取锁,一旦获取到锁,才能继续执行。
3.线程间通信
wait()、notify()和notifyAll()方法是实现线程间通信的关键。通过调用wait()方法,线程可以等待某个条件的满足;而通过notify()或notifyAll()方法,线程可以通知其他等待的线程条件已经满足,从而让它们继续执行。
综上所述,wait()、notify()和notifyAll()方法必须与synchronized关键字一起使用,以确保线程安全、正确释放和恢复监视器锁,并实现有效的线程间通信。