Java中的wait/notify/notifyAll

wait、notify、notifyAll都是java.lang.Object类中的方法:

public final native void wait() throws InterruptedException;
public final native void wait(long millis, int nanos) throws InterruptedException;
public final void wait(long millis) throws InterruptedException {
    wait(millis, 0);
}

public final native void notify();
public final native void notifyAll();

wait():使调用该方法的线程释放锁,从运行状态退出,进入等待队列,直到被唤醒。

wait(long timeout):等待一段时间是否有线程唤醒锁,如果没有,超时自动唤醒。

wait(long timeout, int nanos):等待唤醒时间纳秒级别。

notify():随机唤醒等待队列中的等待同一个锁的一个线程,使这个线程退出等待队列,进入可运行状态。

notifyAll():唤醒所有等待同样锁的所有线程,从等待队列中退出,进入可运行状态。

注意点:

  1. 在调用wait或者notify之前,必须获得该对象的对象锁,即,只能在同步方法中调用;
  2. 执行完wait之后释放对象锁,所以其他线程可以获得执行机会,才能唤醒;
  3. 执行notify之后,不会立即退出让wait的线程执行,必须要先把同步块中的程序执行完,退出同步块,才会释放锁,让等待线程执行;
  4. notify每次通知一个线程,多次调用通知线程数增加,可将wait线程全部唤醒。

Notify和NotifyAll的区别:

先说两个概念:锁池和等待池

  • 锁池:假设线程A已经拥有了某个对象(注意:不是类)的锁,而其它的线程想要调用这个对象的某个synchronized方法(或者synchronized块),由于这些线程在进入对象的synchronized方法之前必须先获得该对象的锁的拥有权,但是该对象的锁目前正被线程A拥有,所以这些线程就进入了该对象的锁池中。
  • 等待池:假设一个线程A调用了某个对象的wait()方法,线程A就会释放该对象的锁后,进入到了该对象的等待池中

再来说notify和notifyAll的区别:

  • 如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁
  • 当有线程调用了对象的 notifyAll()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只要一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争
  • 优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值