CLH同步队列是怎么实现非公平和公平的

CLH同步队列

The wait queue is a variant of a “CLH” (Craig, Landin, and Hagersten) lock queue. CLH locks are normally used for spinlocks

1、名称:CLH 由三个人名字组成 (Craig, Landin, and Hagersten)
2、数据结构:FIFO双向链表
3、作用:等待资源释放的队列

实现非公平和公平

公平锁和非公平锁在于hasQueuedPredecessors()这个方法

public final boolean hasQueuedPredecessors() {
    Node t = tail; 
    Node h = head;
    Node s;
    // 头节点不是尾节点
    // 第一个节点不为空
    // 当前节点是头节点
    return h != t &&
        ((s = h.next) == null || s.thread != Thread.currentThread());
}

线程在doAcquire方法中获取锁时,会先加入同步队列,之后根据情况再陷入阻塞。当阻塞后的节点一段时间后醒来时,这时候来了更多的新线程来抢锁,这些新线程还没有加入到同步队列中去,也就是在tryAcquire方法中获取锁

在公平锁下,这些新线程会发现同步队列中存在节点等待,那么这些新线程将无法获取到锁,去排队;

而在非公平锁下,这些新线程会跟排队苏醒的线程进行锁争抢,失败的去同步队列中排队。因此这里的公平与否,针对的其实是苏醒线程与还未加入同步队列的线程,而对于已经在同步队列中阻塞的线程而言,它们内部自身其实是公平的,因为它们是按顺序被唤醒的,这是根据AQS节点唤醒机制和同步队列的FIFO特性决定的。

你可能感兴趣的:(多线程及并发)