我正在开发一项功能,需要一种读/写锁的变体,该变体可以允许并发多个写入者。
标准读/写锁允许多个读取器或单个写入器同时运行。我需要一个可以同时允许多个读者或多个作者的变体。因此,它永远不应该允许读者和作者同时存在。但是,可以同时允许多个作者或多个读者。
我希望我说清楚了。到目前为止我找不到任何现有的算法。我可以想出几种方法来使用一些队列等来做到这一点。但是,我不想冒险自己做这件事,除非不存在。
你们知道现有的方案吗?
Thanks,
您正在寻找的概念是可重入锁。如果锁已经被占用,您需要能够尝试获取锁并且不会被阻塞(这称为可重入锁)。 Java 中有可重入锁的本机实现,因此我将用 Java 来说明这个示例。 (http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/ReentrantLock.html).
因为当使用 tryLock() 时,如果锁不可用,您不会被阻止,您的写入器/读取器可以继续。但是,只有当您确定没有人在读/写时,您才想释放锁,因此您需要保留读者和作者的计数。您需要同步此计数器或使用允许原子递增/递减的本机atomicInteger。在这个例子中,我使用了原子整数。
Class ReadAndWrite {
private ReentrantLock readLock;
private ReentrantLock writeLock;
private AtomicInteger readers;
private AtomicInteger writers;
private File file;
public void write() {
if (!writeLock.isLocked()) {
readLock.tryLock();
writers.incrementAndGet(); // Increment the number of current writers
// ***** Write your stuff *****
writers.decrementAndGet(); // Decrement the number of current writers
if (readLock.isHeldByCurrentThread()) {
while(writers != 0); // Wait until all writers are finished to release the lock
readLock.unlock();
}
} else {
writeLock.lock();
write();
}
}
public void read() {
if (!readLock.isLocked()) {
writeLock.tryLock();
readers.incrementAndGet();
// ***** read your stuff *****
readers.decrementAndGet(); // Decrement the number of current read
if (writeLock.isHeldByCurrentThread()) {
while(readers != 0); // Wait until all writers are finished to release the lock
writeLock.unlock();
}
} else {
readLock.lock();
read();
}
}
这里发生了什么事:首先,您检查您的锁是否已锁定,以了解您是否可以执行您要执行的操作。如果它被锁定,则意味着您无法读取或写入,因此您使用锁定将自己置于等待状态,并在再次释放锁定时重新调用相同的操作。
如果它没有被锁定,那么您可以使用 tryLock 锁定其他操作(如果您要读取,则锁定写入,反之亦然)。如果已经锁定,tryLock 不会阻塞,因此多个写入者可以同时写入,多个读取者可以同时读取。当与你做同样事情的线程数量达到 0 时,这意味着无论谁首先持有锁,现在都可以释放它。此解决方案的唯一不便之处在于,持有锁的线程必须保持活动状态,直到每个人都完成操作才能释放它。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)