ReadWriteLock

1. Read/write the top interface of the Lock. 2Copy the code

ReentrantReadWriteLock

ReadWriteLock implementation class member variable: ReentrantReadWriteLock. ReadLock readerLock (read lock) ReentrantReadWriteLock. WriteLock writerLock (write) the Sync Sync (synchronizer) Both read and write locks implement Lock interfacesCopy the code

The sample code

private ReadWriteLock lock = new ReentrantReadWriteLock();
	
	
public void method(a) {

    lock.readLock().lock();
    //lock.writeLock().lock();

    try {

        Thread.sleep(1000);
        System.out.println("hello");

    } catch (Exception e) {
        e.printStackTrace();
    } finally {

        lock.readLock().unlock();
        //lock.writeLock().unlock();}}Copy the code

ReentrantReadWriteLock constructor

// fair indicates whether the lock is fair. The default value is unfair
public ReentrantReadWriteLock(boolean fair) {
	// Create a synchronizer
    sync = fair ? new FairSync() : new NonfairSync();
    // Pass the current object into the read/write lock, mainly using its synchronizer
    readerLock = new ReadLock(this);
    writerLock = new WriteLock(this);
}

Copy the code

ReadLock.lock()

public void lock(a) {
	// Because the read lock is shared, the synchronizer's acquireShared method is called
    sync.acquireShared(1);
}

public final void acquireShared(int arg) {
	// The structure of the acquire method is familiar
    if (tryAcquireShared(arg) < 0)
    	// Failed to obtain the lock and entered the waiting queue
        doAcquireShared(arg);
}

protected final int tryAcquireShared(int unused) {
    /* * Walkthrough: * 1. If write lock held by another thread, fail. * 2. Otherwise, this thread is eligible for * lock wrt state, so ask if it should block * because of queue policy. If not, try * to grant by CASing state and updating count. * Note that step does not check for reentrant * acquires, which is postponed to full version * to avoid having to check hold count in * the more typical non-reentrant case. * 3. If step 2 fails either because thread * apparently not eligible or CAS fails or count * saturated, chain to version with full retry loop. */
     // Get the current thread
    Thread current = Thread.currentThread();
    // Get the value of state
    int c = getState();
    //exclusiveCount specifies the number of exclusive locks (write locks)
    // If the write lock exists and the exclusive thread is not the current thread, return -1
    if(exclusiveCount (c) ! =0&& getExclusiveOwnerThread() ! = current)return -1;
        // Get the number of read locks
    int r = sharedCount(c);
    // The readerShouldBlock method is used to determine whether the lock is eligible for a lock
    // r < MAX_COUNT indicates the maximum number of locks
    CompareAndSetState Indicates whether the CAS operation is successful
    if(! readerShouldBlock() && r < MAX_COUNT && compareAndSetState(c, c + SHARED_UNIT)) {if (r == 0) {
            firstReader = current;
            firstReaderHoldCount = 1;
        } else if (firstReader == current) {
            firstReaderHoldCount++;
        } else {
            HoldCounter rh = cachedHoldCounter;
            if (rh == null|| rh.tid ! = getThreadId(current)) cachedHoldCounter = rh = readHolds.get();else if (rh.count == 0)
                readHolds.set(rh);
            rh.count++;
        }
        return 1;
    }
    return fullTryAcquireShared(current);
}

Copy the code

writeLock.lock()

public void lock(a) {
    sync.acquire(1);
}

public final void acquire(int arg) {
    if(! tryAcquire(arg) && acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) selfInterrupt(); }protected final boolean tryAcquire(int acquires) {
    /* * Walkthrough: * 1. If read count nonzero or write count nonzero * and owner is a different thread, fail. * 2. If count would saturate, fail. (This can only * happen if count is already nonzero.) * 3. Otherwise, this thread is eligible for lock if * it is either a reentrant acquire or * queue policy allows it. If so, update state * and set owner. */
    Thread current = Thread.currentThread();
    int c = getState();
    int w = exclusiveCount(c);
    // if c is not 0, some thread holds the lock.
    // Write lock feature, this lock thread unless its own thread, reentrant
    if(c ! =0) {
        // (Note: if c ! = 0 and w == 0 then shared count ! = 0)
        // Must be the current thread
        if (w == 0|| current ! = getExclusiveOwnerThread())return false;
        if (w + exclusiveCount(acquires) > MAX_COUNT)
            throw new Error("Maximum lock count exceeded");
        // Reentrant acquire
        setState(c + acquires);
        return true;
    }
    // Check whether there is a lock condition
    // 1. WriterShouldBlock fair and unfair different processing, if the lock is fair to determine whether there is no thread in the wait queue
    //2. Check whether the CAS operation is successful
    if(writerShouldBlock() || ! compareAndSetState(c, c + acquires))return false;
    // Succeeded in setting the exclusive thread to acquire the lock
    setExclusiveOwnerThread(current);
    return true;
}
Copy the code