ReentrantLock 公平锁

  1. 创建锁对象

因为ReentrantLock默认非公平锁,这里不做考虑,直接构建有参公平锁

public ReentrantLock(boolean fair) {
        this.sync = (ReentrantLock.Sync)(fair ? new ReentrantLock.FairSync() : new ReentrantLock.NonfairSync());
    }

根据入参fair我们可以看到锁同步对象为ReentrantLock.FairSync()

static final class FairSync extends ReentrantLock.Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        FairSync() {
        }

        @ReservedStackAccess
        protected final boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            int c = this.getState();
            if (c == 0) {
                if (!this.hasQueuedPredecessors() && this.compareAndSetState(0, acquires)) {
                    this.setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (current == this.getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) {
                    throw new Error("Maximum lock count exceeded");
                }

                this.setState(nextc);
                return true;
            }

            return false;
        }
    }

公平同步锁继承Sync,且里面只有一个方法

  1. 获取锁tryAcquire
protected final boolean tryAcquire(int acquires) {
//获取当前线程
            Thread current = Thread.currentThread();
//            获取该锁当前状态
            int c = this.getState();
//			状态为0,可以获取锁            
            if (c == 0) {
            //  !this.hasQueuedPredecessors() 成立,cas状态0->1  ======》当前线程获取锁
                if (!this.hasQueuedPredecessors() && this.compareAndSetState(0, acquires)) {
                    this.setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (current == this.getExclusiveOwnerThread()) {
            //当前线程与获取锁线程相同,重入且状态计数值+1
                int nextc = c + acquires;
                if (nextc < 0) {
                    throw new Error("Maximum lock count exceeded");
                }

                this.setState(nextc);
                return true;
            }

            return false;
        }
  1. !this.hasQueuedPredecessors() 延申
    相关代码如下:
public final boolean hasQueuedPredecessors() {
        AbstractQueuedSynchronizer.Node h;
        //判断队列头是否为null
        if ((h = this.head) != null) {
        	//头不为null,创建临时节点s
            AbstractQueuedSynchronizer.Node s;
            
            if ((s = h.next) == null || s.waitStatus > 0) {
            //赋值h.next给s,如果赋值后s为空,或者waitStatus 大于0,重置s
                s = null;
//复制链表队尾给临时节点p ,当p不等于队首,且不等于null时,p不断置换为p上一节点,循环
                for(AbstractQueuedSynchronizer.Node p = this.tail; p != h && p != null; p = p.prev) {
                //临时节点p等待状态小于等于0时,复制p给s
                    if (p.waitStatus <= 0) {
                        s = p;
                    }
                }
            }
//s不为null且不属于当前线程,返回true
            if (s != null && s.thread != Thread.currentThread()) {
                return true;
            }
        }

        return false;
    }

方法中维护了3个临时节点,h、s、p
条件1:
h=当前队首,判断队首为null,说明排队队列没有线程,直接跳出代码返回false (!this.hasQueuedPredecessors()为true直接获取锁)
条件2:
队首不为null,当node.next为空,或者等待状态大于0,重置s为null,赋值p为队尾,根据条件p不等于null且p不等于队首,队尾向前迭代------->迭代过程中找到node等待状态小于等于0,赋值给s,进入下级判断,s!=null,返回true (!this.hasQueuedPredecessors()为false取锁失败)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值