java面试时,并发编程是高频考点之一, 这个上面出现频率非常高的面试题,回答者通常回答不够完善,回答片面,下面来看看标准的答案:
根据字面意思,notify()为随机唤醒一个线程,而notifyAll()是唤醒所有的线程。换句话来说,就是任何时候只有一个线程能获得锁,执行Synchronized中的内容,其它线程被阻塞等待,使用notifyAll()可以唤醒所有的线程重新加入争抢锁的队列中,而notify()只能随机唤醒一个。
这就导致了notify()可能会造成死锁,而notifyAll()不会。
notify() 是对notifyAll()的一个优化,但它有很精确的应用场景,并且要求正确使用。不然可能导致 死锁。正确的场景应该是 WaitSet中等待的是相同的条件,唤醒任一个都能正确处理接下来的事 项,如果唤醒的线程无法正确处理,务必确保继续notify()下一个线程,并且自身需要重新回到 WaitSet中.
为什么会造成死锁?
notify()只唤醒一个正在等待的线程,当该线程执行完以后施放该对象的锁,而没有再次执行notify()方法,则其它正在等待的线程则一直处于等待状态,不会被唤醒而进入该对象的锁的竞争池,就会发生死锁