美文网首页
AQS源码解析(4)tryAcquire

AQS源码解析(4)tryAcquire

作者: 三斤牛肉 | 来源:发表于2021-01-07 14:16 被阅读0次

    之前的acquire函数会先调用tryAcquire去尝试获得锁,这个在每个具体类中实现,这里看ReentrantLock中2个实现。
    公平锁FairSync中:

    protected final boolean tryAcquire(int acquires) {
                final Thread current = Thread.currentThread();
                int c = getState();
                if (c == 0) {//状态为0表示可以加锁
                    if (!hasQueuedPredecessors() && //hasQueuedPredecessors表示之前的线程是否有在排队的,这里加了!表示没有排队
                        compareAndSetState(0, acquires)) { //那么就去尝试cas state
                        setExclusiveOwnerThread(current); //如果cas成功设置排他线程为当前线程,表示成功得到锁
                        return true;
                    }
                }
                else if (current == getExclusiveOwnerThread()) {//如果当前的排他线程是当前线程,表示是重入
                    int nextc = c + acquires; //重入计数器增加
                    if (nextc < 0)
                        throw new Error("Maximum lock count exceeded");
                    setState(nextc);//因为已经获得锁了,所以不用cas去设,直接设值就行
                    return true;
                }
                return false;
            }
    

    非公平锁中:

    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) {//不同于公平锁中,没有hasQueuedPredecessors这个函数,表示当非公平锁去加锁的时候,不会去看有没有线程在排队,直接去抢锁,如果抢到了后续一样。否则会去排队(后续代码再看)
              //之前课程上讲过”一朝排队永远排队“就是这个意思,排队中的非公平并不会去抢先
                    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;
            }
    

    相关文章

      网友评论

          本文标题:AQS源码解析(4)tryAcquire

          本文链接:https://www.haomeiwen.com/subject/fncooktx.html