我正在阅读 java.util.concurrent.locks.Condition
中的条件。
Condition factors out the Object monitor methods (wait, notify and notifyAll) >into distinct objects to give the effect of having multiple wait-sets per object, by combining them with the use of arbitrary Lock implementations.
有人能给我解释一下吗?
这与普通同步块(synchronized block)或方法相比有何优势?
最佳答案
一个锁可以关联多个条件。锁是一个“对象”,每个条件都是一个“等待集”。这允许独立条件共享临界区。例如,考虑有界生产者-消费者问题。解决它的一种方法是有一个保护队列的锁,以及两个独立的等待集:一个用于生产者,等待槽将项目放入队列中,另一个用于等待项目被拿走的消费者。使用普通的旧 synchronized
和 wait/notify
API,我们能做的最好是沿着这些路线:
制作人:
synchronized (lock) { while (queue.isFull()) { lock.wait(); } queue.put(sth); lock.notify(); }
消费者:
synchronized (lock) { while (queue.isEmpty() { lock.wait(); } product = queue.take(); lock.notify(); }
这有一个缺点,即在队列每次更改时都会唤醒生产者和消费者,即使它不可能允许给定的线程继续进行(例如,当其他消费者从队列)。使用 Lock/Condition API,我们可以实现将等待的消费者和生产者分开的解决方案,从而减少冗余的唤醒和检查:
Lock lock = new ReentrantLock();
Condition hasPlace = lock.newCondition();
Condition hasItems = lock.newCondition();
制作人:
lock.lock(); try { while (queue.isFull()) { hasPlace.await(); } queue.put(sth); hasItems.signal(); } finally { lock.unlock(); }
消费者:
lock.lock(); try { while (queue.isEmpty()) { hasItems.await(); } product = queue.take(); hasPlace.signal(); } finally { lock.unlock(); }
这样,消费者等待生产者生产一些元素(hasItems 条件),并在从队列中删除一个元素时通知生产者有一个空槽(hasPlace 条件)。这两种情况都与相同的临界区(锁)相关联,因此我们保留了通常的排除和等待时释放锁的保证,同时获得了分离等待队列的能力。
关于java - 条件给出了每个对象有多个等待集的效果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18490636/