如何使用AQS实施不公平锁定?

时间:2019-03-20 07:29:16

标签: java multithreading locking

最近我看到了AQS的源代码,现在我有很多问题。

final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.predecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
    int ws = pred.waitStatus;
    if (ws == Node.SIGNAL)
        return true;
    if (ws > 0) {
        do {
            node.prev = pred = pred.prev;
        } while (pred.waitStatus > 0);
        pred.next = node;
    } else {
        compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
    }
    return false;
}

这些是源代码旋转请求锁定。而且我们意识到队列中的大多数线程将被驻留。

public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}

在unparkSuccessor中,下一个线程将被唤醒。因此,如果线程第一次无法获取,它将被停放并在队列中等待唤醒。它仍然需要顺序唤醒。我在ReentrantLock中查看了NonfairSync,一旦线程插入队列,它将是FIFO。我认为这只是实施相对不公平。我不知道这是否正确。

0 个答案:

没有答案