对于 Java 中的 MCS Lock,我得到了一些非常奇怪的缓存行为。基本上,它最多可用于四个线程(我机器上的内核数),但会卡住更多。当我调试时,我看到程序卡在了线上
while (qnode.locked);
在 lock() 函数内部。调试时,我可以看到其中一个线程的 QNode 已锁定设置为 false,但我猜这是因为调试器导致缓存更新。我只是将“易失性”扔到所有变量上,绝望地尝试无济于事。这是我正在使用的课程:
class MCSLock
{
private volatile AtomicReference<QNode> tail;
private volatile ThreadLocal<QNode> myNode;
public MCSLock()
{
tail = new AtomicReference<QNode>(null);
myNode = new ThreadLocal<QNode>()
{
protected QNode initialValue() { return new QNode(); }
};
}
public void lock()
{
QNode qnode = myNode.get();
QNode pred = tail.getAndSet(qnode);
if (pred != null)
{
qnode.locked = true;
pred.next = qnode;
while (qnode.locked);
}
}
public void unlock()
{
QNode qnode = myNode.get();
if (qnode.next == null)
{
if (tail.compareAndSet(qnode, null)) return;
while (qnode.next == null);
}
qnode.next.locked = false;
qnode.next = null;
}
private class QNode
{
volatile boolean locked = false;
volatile QNode next = null;
}
}