公平锁与非公平锁

文章前先借用徐志毅大神的一张图公平锁与非公平锁.jpg

出自一张图读懂非公平锁与公平锁


我们可以看出,公平锁与非公平锁的区别在于线程获取锁的方式上。我们假设当前持有锁的线程为甲,现在有线程乙在队列中等待,有线程丙过来获取锁,假设此时甲恰好执行完毕,释放了锁。

公平锁:先去等待队列中看一看,如果有等待的队列,则优先让队头的乙来获取锁。丙加入等待队列继续等待

非公平锁:丙调用cas先抢占了锁,乙继续在等待队列中等待。

我们来看看 ReentrantLock对这两者的实现

//公平锁
protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
      	    //甲释放了锁,c已经变成了0
            if (c == 0) {
                //先看看等待队列是否有线程,有乙在等待,丙获取锁失败
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

//非公平锁
final void lock() {
            //如果甲在这里就释放了锁,丙在此处就获取锁成功
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
		//如果失败继续尝试获取锁,最终调用Sync.nonfairTryAcquire()方法
                acquire(1);
        }


 final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
      	    //甲释放了锁,c已经变成了0
            if (c == 0) {
		//调用cas先将state置为1,抢占锁,丙成功获取到锁
                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;
        }

标题:公平锁与非公平锁
作者:MarsChan
地址:https://marscheng.cn/articles/2020/06/21/1592728090485.html