【并发编程】wait、notify()和notifyAll()之间的联系


参考知乎高👍回答java中的notify和notifyAll有什么区别?


锁池与等待池

首先要明白锁池等待池的区别,现在有一个线程A拥有了Obj对象的锁:

锁池:这时候有其他的线程要来竞争这个对象锁,但是线程A在占用这个对象锁,因此其余的线程都在这个Obj对象的锁池中。

等待池:线程A调用了对象Obj的wait()方法,线程A就会释放Obj的对象锁,进入到该对象的等待池中。


执行wait()方法

一个对象调用了wait()方法,则线程会处于该对象的等待池中,等待池中的线程不会去竞争该对象


调用notify()/notifyAll()方法

但是对象调用了notify()/notifyAll方法之后,就会唤醒等待池中的线程,被唤醒的线程会进入到该对象的锁池中。notify()会唤醒一个线程从等待池到锁池,而notifyAll()会唤醒该对象等待池中的所有对象进入到锁池中,准备竞争这个对象锁。

一般来说,高优先级的线程更容易竞争到这个Obj对象锁,一旦竞争到了,就正常执行synchronized方法,执行完毕之后,其余的线程继续竞争Obj。没有竞争成功的线程依旧留在对象的锁池中。

因此,notify()和notifyAll()共同的作用就是将线程从对象的等待池转移到对象的锁池,区别在于前者是唤醒一个线程,后者是唤醒所有等待线程


notify()可能导致死锁

以上的内容也可以用来解释为什么notify()可能会导致死锁,但是notifyAll()并不会:

假如说这个时候Obj的等待池中,已经有线程A, B, C了,此时线程D持有Obj的锁,调用Obj的wait()方法,此时线程D也进入到了等待池中,Obj锁池中的线程得到Obj之后,就再也没有执行过notify()方法,则导致等待池中的线程一直都处于等待状态,永远不会被唤醒进入到该对象的锁池,因此解决的方法就是执行notifyAll(),唤醒所有的等待线程,防止出现死锁情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YuanbaoQiang

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值