我正在寻找有关如何使用 Java 中的锁使此代码线程安全的建议。我知道锁有很多问题;可能出现的模糊问题、竞争条件等。这是我想要实现的基本想法,但实现得相当天真:
public class MultipleThreadWriter {
boolean isUpgrading=false;
boolean isWriting=false;
public void writeData(String uniqueId) {
if (isUpgrading)
//block until isUpgrading is false
isWriting = true;
{
//do write stuff
}
isWriting = false;
}
public void upgradeSystem() {
if (isWriting)
//block until isWriting is false
isUpgrading = true;
{
//do updates
}
isUpgrading = false;
}
}
基本思想是允许多个线程同时写入数据。这并不重要,因为没有两个线程会写入属于同一 uniqueId 的数据。然而,“系统升级”操作的是所有uniqueId的数据,因此它必须阻塞(排队等待)直到没有数据被写入才可以开始,此时它会阻塞所有写入直到完成。 (这绝对不是这里发生的消费者/生产者模式 - 升级是任意发生的,即与正在写入的数据无关。)
最佳答案
这听起来像是 readers-writer lock 的一个很好的应用程序。 .
但是,在这种情况下,您的“读取器”是可以同时运行的小型更新任务,而您的“写入器”是系统升级任务。
Java 标准库中有一个实现:
java.util.concurrent.locks.ReentrantReadWriteLock
锁有公平和非公平模式。如果您希望系统升级在安排后尽快运行,请使用锁的公平模式。如果您希望在空闲时间(即等到没有小更新发生)应用升级,那么您可以使用非公平模式。
由于这是读写锁的一种非正统应用(你的读者实际上也在写!),所以请确保在你的代码中对此进行良好的注释。您甚至可以考虑围绕提供 localUpdateLock
与 globalUpdateLock
方法的 ReentrantReadWriteLock
类编写一个包装器,后者委托(delegate)给 readLock
> 和 writeLock
分别。
关于java - 使用 Java 队列锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40454484/