Condition.await, signal 与 Object.wait, notify 的区别

Object 类中 wait,notify 与 notifyAll 方法可以用来实现线程之间的调度,比如在阻塞队列(BlockingQueue)的实现中,如果队列为空,则所有消费者线程进行阻塞 ( wait ),如果某一个时刻队列中新添加了一个元素,则需要唤醒某个或所有阻塞状态的消费者线程( notify,notifyAll ),同理如果是队列已满,则所有生产者线程都需要阻塞,等到某个元素被消费之后又需要唤醒某个或所有正在阻塞的生产者线程

Condition 的 await,signal, singalAll 与 Object 的 wait, notify, notifyAll 都可以实现的需求,两者在使用上也是非常类似,都需要先获取某个锁之后才能调用,而不同的是 Object wait,notify 对应的是 synchronized 方式的锁,Condition await,singal 则对应的是 ReentrantLock (实现 Lock 接口的锁对象)对应的锁

但这里面有一个最大的问题就是 synchronized 方式对应的 wait, notify 不能有多个谓词条件,Lock 对应的 Condition await, signal 则可以有多个谓词条件

例如队列已满,所有的生产者现场阻塞,某个时刻消费者消费了一个元素,则需要唤醒某个生产者线程,而通过 Object notify 方式唤醒的线程不能确保一定就是一个生产者线程,因为 notify 是随机唤醒某一个正在该 synchronized 对应的锁上面通过 wait 方式阻塞的线程,如果这时正好还有消费者线程也在阻塞中,则很可能唤醒的是一个消费者线程;signalAll 更是会唤醒所有在对应锁上通过 wait 方式阻塞的线程,而不管是生产者还是消费者线程。

本例中所有的生产者线程在 notEmpty 谓词条件上等待,所有的消费者线程在 notFull 谓词条件上等待,当队列是满的时候所有的生产者线程阻塞,添加元素之后则唤醒某个消费者线程,此时则不用担心会唤醒消费者线程

https://my.oschina.net/u/174366/blog/608509

你可能感兴趣的:(Condition.await, signal 与 Object.wait, notify 的区别)