公平锁:是指多个线程按照申请锁的顺序来获取锁,类似排队打饭,有先来后到。
非公平锁:是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。在高并发的情况下,可能会造成优先级反转或者饥饿现象。
Lock lock = new ReentrantLock();
当使用ReentrantLock的空参构造方法时,默认为非公平锁,源码如下:
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
}
那么,如何控制该锁为公平锁呢?查看源码可以发现ReentrantLock的有参构造方法,如下图所示。
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
当boolean类型的fair值为true时,此时创建的锁就是公平锁,代码如下:
// 参数为true时,为公平锁;
// 参数为false时,或者使用空参构造时,为不公平锁;
Lock lock = new ReentrantLock(true);
两者区别
公平锁:在并发环境中,每个线程在获取锁时会先查看此锁维护的等待队列,如果为空,或者是当前线程是等待队列的第一个,就占有锁,否则就加入到等待队列中,按照FIFO的规则处理请求。
非公平锁:直接尝试占有锁资源,如果尝试失败,就采用类似公平锁的方式。较公平锁而言,非公平锁的吞吐量大。
ps:synchronized也是一种非公平锁。