AQS源码解析(4)tryAcquire

2021-01-07  本文已影响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;
        }
上一篇下一篇

猜你喜欢

热点阅读