不公平锁产生的原因的是acquire在enqueue之前,这样后来的线程有可能会较在等待队列中的等待者之前获得锁。barging这个词可以理解为闯入,插队。不公平锁会导致某些线程总是不排队就获得锁,而同时排在队尾的线程总是出现饥饿状态。那么如何获取公平锁呢,Doug Lee页给出了方案,很简单在acquire的时候,首先检查当前线程是否在队列中(对首),如在队列中即可获得,如不在队列中,则乖乖得排在队尾睡大觉(parking)等着排在前面的线程叫醒它(unparking)。
公平锁为啥会影响性能,从code上来看看公平锁仅仅是多了一项检查是否在队首会影响性能,如不是,那么又是在什么地方影响的?假如是闯入的线程,会排在队尾并睡觉(parking)等待前任节点唤醒,这样势必会比非公平锁添加很多paking和unparking的操作,我想这是影响公平锁性能的主要原因。
E文不好,不敢翻译,怕误了各位看官,还是直接贴原文吧
* <p><a name="barging">
Because checks in acquire are invoked before
* enqueuing, a newly acquiring thread may <em>barge</em> ahead of
* others that are blocked and queued. However, you can, if desired,
* define <tt>tryAcquire</tt> and/or <tt>tryAcquireShared</tt> to
* disable barging by internally invoking one or more of the inspection
* methods,
thereby providing a <em>fair</em> FIFO acquisition order.
* In particular, most fair synchronizers can define <tt>tryAcquire</tt>
* to return <tt>false</tt> if {@link #hasQueuedPredecessors} (a method
* specifically designed to be used by fair synchronizers) returns
* <tt>true</tt>. Other variations are possible.
*
* <p>Throughput and scalability are generally highest for the
* default barging (also known as <em>greedy</em>,
* <em>renouncement</em>, and <em>convoy-avoidance</em>) strategy.
* While this is not guaranteed to be fair or starvation-free, earlier
* queued threads are allowed to recontend before later queued
* threads, and each recontention has an unbiased chance to succeed
* against incoming threads. Also, while acquires do not
* "spin" in the usual sense, they may perform multiple
* invocations of <tt>tryAcquire</tt> interspersed with other
* computations before blocking. This gives most of the benefits of
* spins when exclusive synchronization is only briefly held, without
* most of the liabilities when it isn't. If so desired, you can
* augment this by preceding calls to acquire methods with
* "fast-path" checks, possibly prechecking {@link #hasContended}
* and/or {@link #hasQueuedThreads} to only do so if the synchronizer
* is likely not to be contended.