内容大纲
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状态的线程会去竞争获取锁。