非公平锁

哪怕是有很多的线程在队列里排队,但是当某个线程释放锁的一瞬间,很可能会有其他的晚到的线程突然争抢到了锁。可以看到lock方法中if这里就开始抢锁了,抢不到了再走入队获取锁的流程

  1. final void lock() {
  2. if (compareAndSetState(0, 1))
  3. setExclusiveOwnerThread(Thread.currentThread());
  4. else
  5. acquire(1);
  6. }

公平锁

image.png
公平锁和非公平锁的区别除了在lock方法这有区别,同时在tryAcquire方法上也是有区别的。公平锁这了多了一个方法做判断
image.png
hasQueuedPredecessors();

  1. public final boolean hasQueuedPredecessors() {
  2. // The correctness of this depends on head being initialized
  3. // before tail and on head.next being accurate if the current
  4. // thread is first in queue.
  5. Node t = tail; // Read fields in reverse initialization order
  6. Node h = head;
  7. Node s;
  8. return h != t &&
  9. ((s = h.next) == null || s.thread != Thread.currentThread());
  10. }

h != t:代表head和tail不一样,代表队列里有人在排队。
(s = h.next) == null:如果head的下一个节点 是null,也是返回true(h!=t判断成功时,这个判断一定不成立的)
s.thread != Thread.currentThread():此时,s节点是head的下一个节点,判断一下第一个等待的节点线程是不是当前的线程,如果是当前线程就可以加锁也就是重入锁的操作。

限时加锁tryLock

加锁时有个时间限制,当时间到了就不再去阻塞加锁了

  1. public boolean tryLock(long timeout, TimeUnit unit)
  2. throws InterruptedException {
  3. return sync.tryAcquireNanos(1, unit.toNanos(timeout));
  4. }