java - 使用 Java 队列锁

标签 java multithreading locking

我正在寻找有关如何使用 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

锁有公平非公平模式。如果您希望系统升级在安排后尽快运行,请使用锁的公平模式。如果您希望在空闲时间(即等到没有小更新发生)应用升级,那么您可以使用非公平模式。

由于这是读写锁的一种非正统应用(你的读者实际上也在写!),所以请确保在你的代码中对此进行良好的注释。您甚至可以考虑围绕提供 localUpdateLockglobalUpdateLock 方法的 ReentrantReadWriteLock 类编写一个包装器,后者委托(delegate)给 readLock > 和 writeLock 分别。

关于java - 使用 Java 队列锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40454484/

相关文章:

.net - 如果 Windows 服务在停止时不退出线程会发生什么?

linux - Pthreads 作为 UNIX 中同时控制台输入的标准解决方案?

mysql - 一秒内选择过多 - Mysql

multithreading - 无锁同步

java - 当外观和感觉发生变化时如何动态更改图标?

java - Groovy 等价于 java 的没有访问修饰符的声明

java - tomcat的pkcs12证书是否需要加ca证书

java - 将带有 java envers 的审计表移动到新的数据库实例

java - 无法理解 volatile 字段的工作原理以及它们在共享值时如何与多个线程一起工作

windows - 记事本打败了所有人?