非公平锁
哪怕是有很多的线程在队列里排队,但是当某个线程释放锁的一瞬间,很可能会有其他的晚到的线程突然争抢到了锁。可以看到lock方法中if这里就开始抢锁了,抢不到了再走入队获取锁的流程
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
公平锁
公平锁和非公平锁的区别除了在lock方法这有区别,同时在tryAcquire方法上也是有区别的。公平锁这了多了一个方法做判断
hasQueuedPredecessors();
public final boolean hasQueuedPredecessors() {
// The correctness of this depends on head being initialized
// before tail and on head.next being accurate if the current
// thread is first in queue.
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());
}
h != t:代表head和tail不一样,代表队列里有人在排队。
(s = h.next) == null:如果head的下一个节点 是null,也是返回true(h!=t判断成功时,这个判断一定不成立的)
s.thread != Thread.currentThread():此时,s节点是head的下一个节点,判断一下第一个等待的节点线程是不是当前的线程,如果是当前线程就可以加锁也就是重入锁的操作。
限时加锁tryLock
加锁时有个时间限制,当时间到了就不再去阻塞加锁了
public boolean tryLock(long timeout, TimeUnit unit)
throws InterruptedException {
return sync.tryAcquireNanos(1, unit.toNanos(timeout));
}