ReentrantLock中公平锁与非公平锁的实现原理

在java中,一般的锁实现都要借助队列同步器AbstractQueuedSynchronizer,继承它并重写其指定的方法,随后调用同步器提供的模板方法,模板方法最终会再调用到自己重写的方法。tryAcquire(int acquires)就是其中的一个抽象方法,需要重写。


ReentrantLock公平锁与非公平锁的实现原理区别就是抽象方法tryAcquire的实现不同。公平锁的同步器tryAcquire方法如下:

//公平锁
    protected final boolean tryAcquire(int acquires) {
        final Thread current = Thread.currentThread();
        int c = getState();
        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;
    }
}

非公平锁的同步器tryAcquire方法如下

protected final boolean tryAcquire(int acquires) {
    return nonfairTryAcquire(acquires);
}

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;
}

总结:公平锁与非公平锁相比,唯一不同的位置为判断条件多了hasQueuedPredecessors方法,即加入了同步队列的当前节点是否有前驱节点的判断,如果该方法返回true,则表示有线程比当前线程更早地请求获取锁,因此需要等待前驱节点下次呢很难过获取并释放锁之后才能继续获取锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值