Java线程间通讯之wait()、notify()、notifyAll()-等待通知机制(经常面试:锁的释放问题)

2023-06-19 16:03:04 浏览数 (2)


内容大纲



Java线程间通信-等待、通知的实现


  • java.lang.Object#wait()方法的实现

wait方法是Object类的方法。调用此方法会使当前线程进入“预执行队列”中,并在wait所在代码行处停止执行,直到被其他线程通知(notify、notifyAll)或被中断为止。

调用wait方法之前,当前线程必须获取监视器对象锁,即在同步方法或同步块即synchronized上下文中调用此方法。

执行此方法后,当前线程会释放监视器锁,从运行态退出,进入等待队列(注意:java.lang.Thread#sleep(long)方法不会释放监视器锁)。

从wait方法返回前即被notify、notifyAll唤醒后,线程必须重新去获取监视器锁,成功获取锁后才能执行。

java.lang.Object#wait(long)方法表示等待某一时间内是否有线程对其唤醒,如果超时则自动唤醒

需要注意使用while条件避免假唤醒

示例代码:

代码语言:javascript复制
synchronized( lockObject )
{ 
  while( ! condition )
  { 
    lockObject.wait();
  }
   
  //take the action here;
}
  • notify、notifyAll方法的实现

此方法必须在同步方法或同步块即synchronized上下文中被调用,即当前线程持有监视器锁。

执行方法后,当前线程不会立即释放当前拥有的监视器锁,必须等待此方法的方法或同步块即synchronized上下文执行完,退出同步,当前线程才会释放锁,此时wait状态的线程才可以去竞争获取监视器锁。

日常开发中我们普遍使用notifyAll方法

小结


Java线程间通讯之wait()、notify()、notifyAll()-等待通知机制,锁的释放问题经常面试。

执行wait后,会释放锁,而java.lang.Thread#sleep(long)方法不会释放监视器锁。

wait的线程,notify()、notifyAll()被唤醒后,必须重新获取锁。

需要注意使用while条件避免假唤醒。

notify()、notifyAll()执行后,并不会立即释放锁,必须退出synchronized上下文后才会释放锁,此时wait状态的线程会去竞争获取锁。


0 人点赞