Condition 的哪些实现不需要当前线程持有锁?
Which implementations of Condition do not require current thread to hold the lock?
最近我读了The Art of Multiprocessor Programming第8章的一些例子,关于“Monitors and Blocking Synchronization”使用signalAll()
的Condition
对象,而不获取与该 Condition
关联的锁。
令人惊讶的是,我没有在 book’s errata 中找到对这些示例的任何修复。此外,他们建议对图 8.12 中 FifoReadWriteLock
的示例进行更正,但他们继续使用 signalAll()
而没有持有锁。这让我感到不安,我试图找到关于这些示例的其他注意事项,以了解这些 Java 示例以这种方式编写的原因。
例如,answer to the question “How does a read-write mutex/lock work?”显示了实现 FifoReadWriteLock
的相同示例,它实现了 writeUnlock()
为:
void writeUnlock() {
writer = false;
condition.signalAll();
}
关于没有获取锁你可以读到两个不同的原因:
- 仅作为伪代码使用
- 条件变量的某些实现不要求持有锁以发出信号。
很难接受第一个参数,因为 book 使用 Java 中的示例并明确表示:
The book uses the Java programming language.
关于第二点,我知道 java.util.concurrent.locks.Condition
中的 Java API 声明 signal()
方法:
An implementation may (and typically does) require that the current thread hold the lock associated with this Condition
when this method is called.
如果“一个实现可能”,这意味着它不是强制性的。然而,据我所知,我没有发现任何不满足此要求的实现。所以我想知道 Java Condition
的哪些实现不需要当前线程持有锁?
我不知道 JDK 中的任何 Condition
实现允许在不同时拥有监视器的情况下等待或发出信号。
几乎所有 java.util.concurrent
类 都依赖于 AbstractQueuedSynchronizer
,它与内置监控方法 wait()
/notify()
/ 建立相同的契约notifyAll()
用于它提供的条件变量,即它需要拥有内部锁才能允许调用 await()
/signal()
/signalAll()
.
如果您使用建议的 FifoReadWriteLock
尝试一个简单的示例,您会发现它会由于其 writeUnlock()
方法而喷出大量 IllegalMonitorStateExceptions
。如果您应用其他方法的锁定尝试最终方法,这些异常就会消失。
虽然确实拥有监视器并不是绝对需要等待或发出信号,但它通常是更可取的方法,因为它可以让您免于读取不稳定的条件,而且它不应该因为内部等待之间的切换而花费太多相同监视器的集合仍然可以相当有效地完成,并且因为大多数情况下您需要它来发送信号和调度而不只是发送信号。
最近我读了The Art of Multiprocessor Programming第8章的一些例子,关于“Monitors and Blocking Synchronization”使用signalAll()
的Condition
对象,而不获取与该 Condition
关联的锁。
令人惊讶的是,我没有在 book’s errata 中找到对这些示例的任何修复。此外,他们建议对图 8.12 中 FifoReadWriteLock
的示例进行更正,但他们继续使用 signalAll()
而没有持有锁。这让我感到不安,我试图找到关于这些示例的其他注意事项,以了解这些 Java 示例以这种方式编写的原因。
例如,answer to the question “How does a read-write mutex/lock work?”显示了实现 FifoReadWriteLock
的相同示例,它实现了 writeUnlock()
为:
void writeUnlock() {
writer = false;
condition.signalAll();
}
关于没有获取锁你可以读到两个不同的原因:
- 仅作为伪代码使用
- 条件变量的某些实现不要求持有锁以发出信号。
很难接受第一个参数,因为 book 使用 Java 中的示例并明确表示:
The book uses the Java programming language.
关于第二点,我知道 java.util.concurrent.locks.Condition
中的 Java API 声明 signal()
方法:
An implementation may (and typically does) require that the current thread hold the lock associated with this
Condition
when this method is called.
如果“一个实现可能”,这意味着它不是强制性的。然而,据我所知,我没有发现任何不满足此要求的实现。所以我想知道 Java Condition
的哪些实现不需要当前线程持有锁?
我不知道 JDK 中的任何 Condition
实现允许在不同时拥有监视器的情况下等待或发出信号。
几乎所有 java.util.concurrent
类 都依赖于 AbstractQueuedSynchronizer
,它与内置监控方法 wait()
/notify()
/ 建立相同的契约notifyAll()
用于它提供的条件变量,即它需要拥有内部锁才能允许调用 await()
/signal()
/signalAll()
.
如果您使用建议的 FifoReadWriteLock
尝试一个简单的示例,您会发现它会由于其 writeUnlock()
方法而喷出大量 IllegalMonitorStateExceptions
。如果您应用其他方法的锁定尝试最终方法,这些异常就会消失。
虽然确实拥有监视器并不是绝对需要等待或发出信号,但它通常是更可取的方法,因为它可以让您免于读取不稳定的条件,而且它不应该因为内部等待之间的切换而花费太多相同监视器的集合仍然可以相当有效地完成,并且因为大多数情况下您需要它来发送信号和调度而不只是发送信号。