如何以无锁方式自动更新 2 个对象?

Posted

技术标签:

【中文标题】如何以无锁方式自动更新 2 个对象?【英文标题】:How to update 2 objects atomically in a lock-free manner? 【发布时间】:2015-04-26 13:27:14 【问题描述】:

我正在研究通过多个对象实现基于哈希码的原子锁定的类。主要目的是在所有需要的锁都可用时立即解除等待者线程,从而减少总体等待时间。

它的lockAndGet(List objects) 返回一个涉及所有列出对象的“复合锁”。调用者完成工作后,它会调用unlock()

主要组件有:1)普通锁表--int[]数组显示现在持有哪些锁; 2) 服务员线程的双端队列。

算法很简单:

    当一个线程调用lockAndGet()时,它被标记为停放,然后新的waiter object包含这个线程,状态为LOCKED被创建并添加到队列的尾部,之后makeRound() 方法被调用; makeRound() 从头部开始遍历双端队列,试图找到哪些服务员可以获得他们的锁。当找到一个这样的服务员时,锁表被更新,服务员状态更改为UNLOCKED 并从双端队列中删除,服务员的线程被取消驻留。遍历后,如果当前线程被标记为停放,则停放; 当在某个复合锁上调用unlock() 时,锁表状态会更新并调用makeRound()

这里,为了避免竞争条件,锁表状态的更新必须与等待者状态的更新一起原子地执行。现在,它是通过普通独占Lock上的同步来实现的,并且效果很好,但是我想使用CAS操作以free-lock方式实现类似的机制,使waiter queue无锁。第 1 步很简单,但第 2 步有问题。

由于 Java 不支持 DCAS,有谁知道怎么做 可以实现队列节点的更新(服务员状态的改变和删除标记)原子地更新其他对象(锁表),只使用CAS?我不要求提供代码,只是提供一些可能有所帮助的提示或方法。

【问题讨论】:

您是否真的有性能问题促使您尝试寻找无锁算法?这些很难做到正确。否则有很多解决方案(信号量、锁存器、条件等) @fge 在我目前的方法中,我使用锁和信号量的组合,它工作得非常正确且非常快。但我无法判断只有一种基于锁的实现会更好:没有可比性!无锁并不容易,对吧。我犹豫在 SO 中发布简单的问题。 执行多个值的同步更新基本上有三种方法:1)使用锁,2)使用“安全序列”(很难做到正确,假设甚至有解决方案) , 3) 使用某种机器设备(例如禁用调度程序)。但请注意,“锁”有多种形式——计数器、信号量、操作系统定义的锁等。 【参考方案1】:

您可以尝试使用可用的 CAS 来实现多字 CAS,但这取决于您愿意为实现这一目标付出多少性能损失。

你可以看看哈里斯的http://www.cl.cam.ac.uk/research/srg/netos/papers/2002-casn.pdf

【讨论】:

谢谢,我去看看

以上是关于如何以无锁方式自动更新 2 个对象?的主要内容,如果未能解决你的问题,请参考以下文章

为啥标准库不以无锁方式为 8 字节以下的结构实现 std::atomic?

在类对象中,如何自动更新属性?

Windows开机自动启动VirtualBox(以无界面方式启动)-虚拟机

如何设置windows自动更新的安装目录?

金蝶eas如何关闭自动更新

delphi 自动更新cs客户端的问题