Java Concurrency series -ReentrantLock study notes

ReentrantLock study notes

Internal lock form

  • Fair locks FairSync, a new thread must be blocked at the back of the old thread is blocked grab lock
  • Unfair lock NonfairSync new thread is blocked lock could grab

The default lock form

The default lock unfair, there can be switched to the constructor residues fair, equitable lock performance but certainly not good performance lock unfair

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

Abstract internal lock Sync

Since ReentrantLock is an exclusive lock, so whether it is fair or unfair lock lock, release the lock mode is the same as fairness say is that at the time of acquiring the lock, so Sync implements a method of trying to release the lock tryRelease different fair attempt to acquire the lock of the lock tryAcquire specific method implemented by the sub-class, which is the standard template method pattern. Also defines the lock method lock, because certainly must first obtain a lock before the lock, so this method is an abstract method

    abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        
        abstract void lock();
        //非公平的尝试获取锁
        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()) {
                //多次加锁,state值增加固定值,说明了ReentrantLock是一个可重入锁
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

        protected final boolean tryRelease(int releases) {
            //ReentrantLock的可重入性导致多次释放锁就多次减去相同的值
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            //由于Thread.currentThread() != getExclusiveOwnerThread() 判断的存在,所以不需要考虑线程安全问题
            setState(c);
            return free;
        }
        
        //..........................................
        
    }

Fair lock FairSync

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

        final void lock() {
            //公平锁的获取不会去判断state的状态,获取锁只能依赖tryAcquire的逻辑,所以公平性由tryAcquire保证
            acquire(1);
        }

        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                //核心点hasQueuedPredecessors(),判断当前线程前面还有没有其他线程在排队,如果有返回fasle,如果没有执行获取锁的操作
                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;
        }
    }

Unfair lock NonfairSync

static final class NonfairSync extends Sync {
    private static final long serialVersionUID = 7316153563782823691L;
    //因为是非公平锁,所以新的阻塞节点可以和已经排队的阻塞节点一起竞争锁,而ReentrantLock又是独占锁,state状态为0说明当前所没有被持有,所以不管是新的阻塞点还是旧的阻塞点,只要state状态等于0,就可以尝试去抢占锁
    final void lock() {
        if (compareAndSetState(0, 1))
            setExclusiveOwnerThread(Thread.currentThread());
        else
            //调用AQS的方法
            acquire(1);
    }
    
    protected final boolean tryAcquire(int acquires) {
        return nonfairTryAcquire(acquires);
    }
}

to sum up:

The source code is actually quite simple, as summarized below:

  • Fair and unfair implementation only difference then perhaps lock before determining what is there in front of the current thread waiting now, if there are no returns fasle if it successfully acquired lock, another is fair to acquire the lock mode must rely tryAcquire method.
  • ReentrantLock is reentrant exclusive lock, locked state value plus 1, minus 1 to unlocked, is 0 to show that no lock is idle (jvm like reference counting)
  • ReentrantLock default unfair lock can be specified by structural parameters

Guess you like

Origin www.cnblogs.com/lx-lixiao/p/12149031.html
Recommended