ReentrantLock的公平锁和非公平锁的底层实现主要区别在于获取锁的策略。
-
公平锁(FairSync):当多个线程申请锁时,公平锁会按照线程申请锁的先后顺序,让先来的线程先获取锁,就像排队上厕所的场景,先来的先占用,后来的只能排队等待。这种策略确保了线程按照它们请求锁的顺序来获取锁,从而避免了饥饿问题,即长时间等待的线程最终能够获得锁。
-
非公平锁(NonfairSync):非公平锁允许线程直接竞争锁,如果能够成功获取锁就直接占有,否则再进入队列顺序等待。这种策略下,后来的线程可能会尝试插队,如果成功则直接使用锁,否则需要排队等待。这种策略虽然可能导致一些线程在短时间内获得优势,但从长期来看,它并没有改变每个线程最终都能获得锁的事实。
在ReentrantLock的实现中,FairSync和NonfairSync是两种不同的内部类,分别实现了公平锁和非公平锁的逻辑。当使用无参构造器创建ReentrantLock对象时,默认生成的是NonfairSync对象,即非公平锁。如果希望使用公平锁,需要在创建ReentrantLock对象时传入参数true
。这两种锁的实现都基于AbstractQueuedSynchronizer(AQS)框架,但tryAcquire方法的实现不同,决定了线程获取锁的方式和顺序。