The main difference between fair and AQS implementations of the JUC package is that in an unfair lock, the thread that attempts to acquire the lock and has not entered the wait queue competes with the thread that waits for the queue head node. In a fair lock, the Isfirst (current) judgment is added when the lock is acquired, only if and only if the wait queue is empty or the current thread is the header node of the waiting queue.
1.1 nonfairsync.lock () Java Code final void lock () {if (compareandsetstate (0, 1))//Does not enter the wait queue or can acquire a lock setexc Lusiveownerthread (Thread.CurrentThread ()); else acquire (1); }
2.1 fairsync.lock () Java Code final void Lock () {acquire (1); }
2.2 Fairsync.tryacquire () Java code /** * fair version of tryacquire. don ' t grant access unless * recursive call or no waiters or is first. */ protected final boolean tryacquire (Int acquires) { final thread current = thread.currentthread (); int c = getstate (); if (c == 0) { if (Isfirst (current) &&// Locks can be acquired only if the wait queue is empty or if the current thread is a queue header node compareandsetstate (0, acquires)) { setexclusiveownerthread (current); return true; } } else if (Current == getexclusiveownerthread ()) { &NBSP;&NBSP;&NBSP;&NBsp; int nextc = c + acquires; if (nextc < 0) throw new error ("Maximum lock count exceeded "); setstate (NEXTC); return true; } return false; }
For more information on whether the current thread is a queue header node, see the following two functions:
2.3 Abstractqueuedsynchronizer.isfirst () Java code /** * return {@code true} if the queue is empty or if the given thread * is at the head of the queue. this is reliable only if * <tt> Current</tt> is actually thread.currentthread () of caller. */ final boolean isfirst (thread current) { Node h, s; return ((h = head) == null | | ( S = h.next) ! = null && s.thread == current) | | Fullisfirst (current); }
2.4 abstractqueuedsynchronizer.fullisfirst () Java code final boolean fullisfirst (thread Current) { // same idea as fullGetFirstQueuedThread Node h, s; Thread firstThread = null; if ((h = head) != null && (s = h.next) != null && s.prev == head && ( Firstthread = s.thread) != null) return firstThread == current; node t = tail; while (t != null && t != head) { Thread tt = t.thread; if (tt != null) firstThread = tt; &nbs