Skip to content

公平锁和非公平锁

公平锁的特点:

  • 公平锁是指多个线程按照申请锁的顺序来获取锁。
  • ReentrantLock和synchronized都可以实现公平锁。
    • ReentrantLock 实现公平锁的方式是通过构造函数传入true来实现。
    • synchronized 是非公平锁,但是可以通过LockSupport.park()和LockSupport.unpark()来实现公平锁。

非公平锁的特点:

  • 非公平锁是指多个线程获取锁的顺序是不定的。
  • ReentrantLock和synchronized都可以实现非公平锁。
    • ReentrantLock 实现非公平锁的方式是通过构造函数传入false来实现。
    • synchronized 是非公平锁,但是可以通过LockSupport.park()和LockSupport.unpark()来实现公平锁。

两者的区别:

  • 公平锁的优点是等待时间长的线程会先获取锁,避免了饥饿现象。
  • 非公平锁的优点在于吞吐量比公平锁大。

公平锁实现的逻辑

  • 公平锁的实现逻辑是通过一个先进先出的队列来实现的。
  • 公平锁的实现底层代码:
java
public class ReentrantLock implements Lock, java.io.Serializable {
    private final Sync sync;

    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        abstract void lock();

        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }
    }
}