我在许多教程中遇到了以下 ReadWriteLock 的不可重入实现。
public class ReadWriteLock{
private int readers = 0;
private int writers = 0;
private int writeRequests = 0;
public synchronized void lockRead() throws InterruptedException{
while(writers > 0 || writeRequests > 0){
wait();
}
readers++;
}
public synchronized void unlockRead(){
readers--;
notifyAll();
}
public synchronized void lockWrite() throws InterruptedException{
writeRequests++;
while(readers > 0 || writers > 0){
wait();
}
writeRequests--;
writers++;
}
public synchronized void unlockWrite() throws InterruptedException{
writers--;
notifyAll();
}
}
问题:
此类的对象(例如 lock
)在所有读取器和写入器线程之间共享以实现同步。
假设读者 T1 调用 lock.lockRead()
,这样就获取了锁对象上的锁,Reader T2同时调用lockRead()
在同一个物体上。但是T1已经锁定了对象,所以T2应该被阻塞并在队列中等待。
那么,代码是如何允许多个读者同时设置readLock的呢?
当我犯错时,请纠正我。
最佳答案
确实没有 2 个线程可以同时执行 lockRead()
方法的主体。但这对于读取器/写入器模式正常工作并达到预期性能来说并不是必需的。
重要的是,如果没有 Activity 的写入者(不调用 wait
),lockRead()
方法会快速返回。当方法结束时锁被释放,从而允许另一个线程也获取读锁。
所以,是的,获取读锁的行为(增加readers
)是序列化的。但它发生得太快了,所以效果很好。
举例说明:
private ReadWriteLock lock = new ReadWriteLock(); // this instance is shared by all threads
public void ReadSomething() {
try {
lock.lockRead(); // serialized, but very quick
PerformWork(); // potentially slower, but is concurrent
} finally {
lock.unlockRead(); // serialized, but very quick
}
}
如果 2 个线程尝试同时运行上述 ReadSomething()
方法,则确实只有一个线程能够执行 lock.lockRead()
一次。但是,一旦该方法为其中一个线程返回,第二个线程也将能够执行它。而且对 lock.lockRead()
的调用发生得非常快,您甚至无法注意到一个线程正在等待另一个线程。
重要的是两个线程都能够同时执行更耗时的 PerformWork()
。
关于java - ReadWriteLocks-(不可重入)它如何支持多个读者获取读锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38621687/