乐趣区

关于java:公平锁和非公平锁的区别

在 java 的锁机制中,偏心和非偏心的参考物是什么,集体而言感觉是绝对产生的后果而立,
简略的来说,如果一个线程组里,能保障每个线程都能拿到锁,那么这个锁就是偏心锁。
相同,如果保障不了每个线程都能拿到锁,也就是存在有线程饿死,那么这个锁就是非偏心锁。

本文围绕 ReenTrantLock 来讲。

实现原理

那如何能保障每个线程都能拿到锁呢,队列 FIFO 是一个完满的解决方案,也就是先进先出,java 的 ReenTrantLock 也就是用队列实现的偏心锁和非偏心锁。
在偏心的锁中,如果有另一个线程持有锁或者有其余线程在期待队列中期待这个所,那么新收回的申请的线程将被放入到队列中。
而非偏心锁上,只有当锁被某个线程持有时,新发出请求的线程才会被放入队列中(此时和偏心锁是一样的)。
所以,它们的差异在于非偏心锁会有更多的机会去抢占锁。

偏心锁:

final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {if (!hasQueuedPredecessors() &&
        compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);
        return true;
    }
}

hasQueuedPredecessors 的实现

public final boolean hasQueuedPredecessors() {

    Node t = tail; // Read fields in reverse initialization order
    Node h = head;
    Node s;
    return h != t &&
        ((s = h.next) == null || s.thread != Thread.currentThread());
}

非偏心锁:

final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);
        return true;
    }
}

本文由猿必过 YBG 公布

退出移动版