【发布时间】:2021-03-08 15:32:23
【问题描述】:
我正在尝试实现一个遵循以下约束的系统:
- 我有一个共享资源,例如原子数组
- 我想同时支持从阵列中进行多次读取。
- 我想同时支持对数组的多次写入
- 我不希望读取和写入操作同时发生。
我发现 [this][1] stackoverflow post 关于类似的目标,但我认为建议的解决方案是允许同时读取和写入:
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();
}
}
在我看来,这段代码允许同时读取和写入,例如:两个线程将尝试同时读取/写入。如果在写/读中,他们每个人都将进入第一个。如何确保写入阻止读取和读取阻止写入? [1]:Multiple readers and multiple writers(i mean multiple) synchronization
【问题讨论】:
-
#tryLock是一个乐观锁,你需要检查返回值以确保你确实获得了锁。如果您因为无法锁定它而想要阻止它,那么您可以调用#lock。另请查看StampedLock -
你是对的,读+写可以同时发生。我不确定这是否是最好的方法,但我认为你可以创建第三个锁
checkLocks,它总是首先被声明,并在检查并声明其他锁后被释放。